퍼블릭 상수를 사용하지 마세요
- 상수 public static final 프로퍼티란?
- 객체 사이에 데이터를 공유하기 위해 사용하는 매우 유명한 매커니즘
- 글자 그대로 상수를 사용하는 이유는 데이터를 공유하기 위해서다.
- 이 이유 때문에 책에서는 반대하고 있다.
- 왜?
- 객체들은 어떤 것도 공유해서는 안된다.
- 대신 독립적이고 닫혀 있어야 한다.
class Records{ private static final String EOL = "\r\n"; void write(Writer out) { for(Record rec : this.all) { out.write(rec.toString()); out.write(Records.EOL); } } }
class Rows{ private static final String EOL = "\r\n"; void print(PrintStream pnt) { for(Row row : this.fetch() { pnt.printf( "{ %s }%s", row, Rows.EOL ) } } }
public class Constants { public static final String EOL = "\r\n"; }
- 그이유는 중복이라는 하나의 문제를 해결하기 위해 결합도가 높아진 것이고 응집도가 낮아진 것이다.
불변 객체로 만드세요.
- 모든 클래스를 상태 변경이 불가능한 불변 클래스로 구현하면 유지보수성을 크게 향상시킬 수 있다.
- 불변성 역시 크기가 작고 응집력이 높으며 느슨하게 결합되고 유지보수하기 쉬운 클래스를 만들 수 있도록 도와준다.
- 가변 클래스보다는 불변 클래스를 이해하는 쪽이 훨씬 수월하다.
- 불변 객체를 기반으로 사고하면 더 깔끔하고 더 작고 더 쉽게 이해할 수 있는 코드를 만들 수 있다.
불변성이란?
- 인스턴스를 생성한 후에 상태를 변경할 수 없는 객체를 불변객체라고 합니다.
class Cash{ private int dollars; public void setDollars(int val) { this.dollars = val; } }
- 다음 클래스는 위의 Cash와 비슷하지만 상태를 변경할 수 없는 불변객체를 생성한다.
class Cash { private final int dollars; Cash(int val) { this.dollars = val; } }
- 달라진 점은 무엇일까?
- private 프로퍼티인 dollars에 final 키워드를 추가했다는 점이다 !
- final 키워드는 생성자 외부에서 프로퍼티의 값을 수정할 경우 컴파일 타임 에러가 발생해야 한다는 사실을 컴파일러에게 알려준다.
- 불변 객체는 필요한 모든 것을 내부에 캡슐화하고 변경할 수 없도록 통제한다.
- 불변 객체를 수정해야 한다면?
- 프로퍼티를 수정하는 대신 새로운 객체를 생성해야 한다 !
그래서 왜 불변을 강조할까?
- 가변 객체는 전반적인 객체 패러다임의 오용입니다.
- five 객체를 만들었는데 이 값이 바뀌면 더이상 five가 아니게된다.
- 가변 객체의 사용을 엄격하게 금지해야 한다.
- Haskell 언어에서 제약하는 방식처럼 OOP 에서도 가변객체가 존재해서는 안된다.
- 지연로딩이란?
- 기술적으로 불변 객체를 사용해서 지연로딩을 구현하는 것은 불가능하다.
- 최소한 자바, 루비, c++과 같은 몇몇 언어에 대해서는 사실이다.
- 지연로딩 기법을 사용하면 다음과 같이 객체가 캡슐화하고 있는 프로퍼티를 업데이트 할 필요가 있을 때 프로퍼티를 게으르게 로드할 수 있다.