이전에 읽을 것 : https://codingnuri.com/seven-virtues-of-good-object/
생각해볼 것
객체의 템플릿이 아닌, 객체의 능동적인 관리자!
public class LottoNumber {
private static final Map<Integer, LottoNumber> cache = new WeakHashMap(45);
// ...
public static LottoNumber of(final int value) {
return cache.computeIfAbsent(value, LottoNumber::new);
}
}
computeIfAbsent
: 값 캐싱 후 반환. 더 알아보기
응집도가 높고 견고한 클래스
생성자를 default
로? 아니면 getter
를?
상속은 코드를 재사용하는 강력한 수단이지만 항상 최선은 아니다. 올바르게 사용하자!
public class Document {
public int length() {
return this.content().length;
}
public byte[] content() {}
}
public class EncryptedDocument extends Document {
@Override
public byte[] content() {}
}
length() 구현을 어떤 클래스에서??
public class LottoNumbers extends HashSet<LottoNumber> {
private int addCount = 0;
@Override
public boolean add(final LottoNumber lottoNumber) {
addCount++;
return super.add(lottoNumber);
}
@Override
public boolean addAll(final Collection<? extends LottoNumber> c) {
addCount += c.size(); //!!!!!!원하는 결과가 안나옴
return super.addAll(c);
}
public int getAddCount() {
return addCount;
}
}
// addAll의 로직은?
public boolean addAll(final Collection<? extends E> c) {
boolean modified = false;
for (E e : c)
if (add(e)) // 이미 여기서 addCount++ 됨
modified = true;
return modified;
}
addAll
에서 addCount+= c.size
-> 안됨!!final
classabstract
class기존 클래스를 확장하는 대신, 새 클래스를 만들고 private 필드로 기존 클래스 인스턴스를 참조
public class Cash {
private int dollars;
public void mul(final int factor) {
this.dollars *= factor;
}
}
mul()을 통해 외부에서 Cash 인스턴스 값 수정 가능. 즉, 가변 객체
모든 클래스를 불변 클래스(immutable class)로 만들자!
불변 객체는 크기가 작다
public class Cash {
private final int dollars;
public Cash mul(final int factor) {
return new Cash(this.dollars * factor);//새 객체 반환
}
}
map.get(five)
사용 시 식별자 변경(identity mutability)’ 문제가 발생하지 않는다.
즉 DTO 사용 없이, 바로 view로 던져도 된다! (VO
)
public class Cash {
private int dollars;
private int cents;
public mul(final int factor) {
this.dollars *= factor;
if (/* 뭔가 잘못 됐다면 */) {
throw new RuntimeException("oops...");
}
this.cents *= factor;
}
}
객체가 완전하고 견고한 상태가 아니면, 실패!
Cash price=new Cash();
price.setDollars(29);
price.setCents(95);
System.out.println(price);// "$29.95"
이펙티브 자바 4장 (스터디 자료)