01. 클래스와 멤버의 접근 권한을 최소화하라
Public class의 instance field
- Public 으로 열 경우 Tread safe하지 못하다
- 꼭 필요한 상수라면 예외적으로 public static final로 공개할 수 있다.
- [주의사항] public static final Thing[] values = {...} 는 수정이 그낭하다
배열의 해결책
배열을 private로 만들고, 불변 리스트를 추가
private static final PAGE[] PAGE_INFO = {...};
public staticf inal List<PAGE> VLAUSE =
Collection.unmodeifiableList(Arrays.asList(PAGE_INFO));
배열을 private로 두고, 복사본을 변환하는 public method
public static final PAGE[] vlause(){
return PAGE_INFO.clone();
}
02. 변경 가능성을 최소화 하라
Immutable class
1. 상태 변경 method를 제공하지 않는다.
2. Class를 확장하지 않도록 한다.
3. 모든 field를 final로 선언한다.
4. 모든 filed를 private로 선언한다.
5. 자신을 제외하고는 아무도 가변 컴포넌트에 접근할 수 없도록 한다.
접근 제어
@Getter
class AddressInfo{
private String address;
}
@AllArgsConstructor
final class User{
private final String phone;
private final List<AddressInfo> addressInfoList;
public List<String getAddressList(){
return addressInfoList.stream()
.map(AddressInfo::getAddress).collect(Collectors.toList());
}
}
BigInteger (Immutable class example)
BigInteger bigInteger = new BigInteger("10000");
System.out.println(bigInteger.add(new BigInteger("100")));
System.out.println(bigInteger);
조건
1. Tread safe
2. failure atomicity ~ 예외가 발생 후에도 유효한 상태
3. 값이 다르면 무조건 독립적인 객체로 생성되어야 함
중간 단계 (객체가 완성 중인 상태)를 극복하기 위한 방법
Static factory method를 통해 new instance를 생성해 response Ex) StringBuilder
03. 상속을 고려해 설계하고 문서화 하라. 그러지 않았다면 상속을 금지하라
상속을 금지하는 법
Class를 final로 선언하는 법
final public class ProhibitIngeritance{
}
모든 생성자를 private or package-private로 선언하고 public static factory로 만드는 법
@Getter
public class ProhibitIngeritance{
private int sum;
private ProhibitIngeritance() {}
private ProhibitIngeritance(int sum){
this.sum = sum;
}
}
요약
웬만하면 interface를 통한 구현
final class보다는 coding rule을 정할 때 웬만하면 상속을 피한다.라고 협의 후 코드 리뷰에 반영하는 편이 더 좋다.
변수 몇 개가 겹친다고 해서 꼭 상속을 통한 확장을 해야 한다는 것을 의미하는 것은 아니다.