상태 없는 객체는 존재해서는 안되고, 상태는 객체의 식별자여야 한다.
4개 이하의 객체로 캡슐화하라고 하지만 너무 원론적이다. 가능하면 상태를 적게 유지하여 복잡성을 줄여 유지보수성을 유지하자. 객체의 책임에 대해서도 생각하자.
저자는 객체의 식별자로 상태로 보기때문에 상태가 없는 객체는 OOP 적으로 맞지 않다고 이야기 하고 있다. 상태가 없다면 자기 자신을 식별하기 위해 다른 객체를 캡슐화 하라고 한다. 순수 OOP 관점에서는 상태가 있는것이 맞는 말인것 같긴하다.
Class Year{
...
Year(final int a){
...
}
}
final
로 받음으로써 생성자는 생성만하라는 책임에서 벗어나 다른 로직이 적용되 값이 변경되는 위험을 줄여줄 수 있다.Cash.cents()
와 같이 강한 결합도가 생기면 동시에 구현을 대체하기 어렵다.복잡성을 줄이기 위해 인터페이스를 사용하자
int pow(int base, int power);
void save(String content);
void saveByDistInYourPocketThisIsWhatYouMustDo(String content);
Boolean
같은 경우 동사가 아닌 형용사를 쓰라며isEmpty
대신empty
를 주장하지만 관습적 사용을 취소하면서 사용명을 바꾸는은 협력관점에서 너무 과도하다고 생각이든다.
빌더와 조정자는 분명 코드 작성을 하면서 동시에 사용하는것이 더 편하고 실제 그렇게 쓰이는 경우도 분명 존재할거라 생각한다. 하지만 명령쿼리분리원칙을 생각한다면 기본적으로 코드작성에서 안전한 방식이라고 생각한다.(명령에서 반환값이 있다면 명령이 실행되는줄 모르고 쿼리로 오해하여 메서드를 사용하는 불상사가 존재할 수 있다. - 쿼리용도인데 알고보니 상태변화 발생...)
토론하기 : http://goo.gl/QlUoru
private static final
을 통해 각 클래스내부에서만 사용하는 변수를 만드는 것은 책임을 아무대나 던져놓는 것과 동일하다.private static final
을 통해서 사용하는 용도를 표현하는 클래스로 감싸주는 것이 더 낫다. 그래야 중복코드를 줄일 수 있지만 기능위주가 아닌 데이터 위주이므로 아직은 협력이라 보기 어렵다.public calss Constants{
public static final String EOL = "\r\n";
}
Constants.EOL
을 통해 하드 코딩을 하게 된다.
Constants.EOL
은 자신에 대해 아무것도 모른다.class Test{
private final String origin;
Test(String src){
this.origin = src;
}
@Override
String toString(){
return String.format("%s\r\m", origin);
}
}
어느정도 공감되는 글이다. 기능위주로 책임을 가지는 객체로 캡슐화하고 상수마다 의미를 캡슐화하라는 말은 인상깊었다. 하지만 열거형을 쓰지 말라는 말은 조금 지나친거 같다. 이미 열거형 자체가 상수가 가지는 문제를 해결하기 위해 나왔고, 다양한 기능들이 제공되기에 열거형에 긍정적이다.
토론하기 : http://goo.gl/zlXGjO
지연 로딩을 캐시로 바꾼다고 하지만 결국 불변객체를 보장하기 위해 가변객체의 캐시를 이용하는 것이므로 완전하지 못한다.
그럼에도 불구하고 불변객체를 쓰자.
저자의 의도대로 기능위주의 자율성있는 객체를 원하면 쓰지 말아야 될거같다.
하지만 열거형이 필요한 용도에 쓰자
public class Test2_5_2 {
public static void main(String[] args) {
Double value = 5d;
System.out.println(MathObject.PIE * MathObject.PIE * value);
Pie pie = new Pie(value);
System.out.println(pie.circleSize());
System.out.println(PieEnum.GET_CIRCLE_SIZE.apply(value));
Double pie1 = PieEnum.pie;
}
class MathObject {
private static final Double PIE = 3.14;
}
static class Pie {
private final Double value;
private final Double pie = 3.14;
public Pie(Double value) {
this.value = value;
}
public Double circleSize() {
return value * value * pie;
}
public Double circleLength() {
return value * pie * 2;
}
}
enum PieEnum {
GET_CIRCLE_SIZE(1) {
public double apply(double value) {
return value * pie * pie;
}
},
GET_CIRCLE_LENGTH(2) {
public double apply(double value) {
return value * pie * 2;
}
};
private static final Double pie = 3.14;
private final int value;
PieEnum(int value) {
this.value = value;
}
public abstract double apply(double x);
}
}