객체지향 원리
캡슐화
- 요구사항의 변경
- 소프트웨어 개발의 골치거리
- 해결책은 요구사항 변경을 당연한 것으로 받아들이고 이에 대비하는 것이다.
- 캡슐화를 통해 높은 응집도와 낮은 결합도를 갖는 설계
- 다음과 같이 클래스 멤버 변수의 접근 제어자를 private으로 설정함으로써 외부에서는 직접 itemArray클래스에 접근할 수 가 없고 push(), pop()메서드를 통해서만 접근이 가능하게 된다
일반화 관계
- 일반화(상속)을 속성이나 기능의 재사용 관점에서만 보는 것은 극히 제한된 관점
- 철학에서 일반화generalization는 “여러 개체들이 가진 공통된 특성을 부각시켜 하나의 개념이나 법칙으로 성립시키는 과정”
- 만약 일반화 개념을 사용하지 않는다면?
- 다음 그림처럼 switch문을 통해 하나씩 어떤 과일인지 체크해야함
- 이를 일반화 개념을 적용한다면?
- 이 코드에선 새로운 과일인 키위가 추가되도 내부로직은 변경되지 않는다.
- 일반화는 클래스 자체를 캡슐화하여 변경에 대비할 수 있는 설계를 가능하게 한다. 즉, 새로운 클래스가 추가되더라도 클라이언트는 영향 받지 않는다.
- 새로운 차량 크루즈가 추가되더라도 사람이 대리운전을 하는 부분에는 전혀 영향을 끼치지 않는다.
- 새로운 차량 크루즈가 추가되더라도 사람이 대리운전을 하는 부분에는 전혀 영향을 끼치지 않는다.
- 자바의 extend키워드는 일반화 관계에서만 쓰는 키워드! 자바에서는 상속관계를 표현할 수 있는 키워드가 없다.(굳이 없어도 상관X, C++은 있다 private inheritance)
일반화와 위임
- 두 자식 클래스 사이에 ‘is a kind of 관계’가 성립되지 않을 때 상속을 사용하면 불필요한 속성이나 연산(빚이라 해도 될 것이다)도 물려받게 된다.
- ArrayList를 상속 받은 MyStack클래스에서 불필요하게 상속받은 set메소드로 인해 스택의 무결성 조건에 위배됨
- 어떤 클래스의 일부 기능만을 사용하고 싶을 경우에는 위임을 사용하라
- 일반화를 위임으로 변환하는 프로세스
- 자식 클래스에 부모 클래스의 인스턴스를 참조하는 속성을 만든다. 이 속성 필드를 this로 초기화한다.
- 서브 클래스에 정의된 각 메서드에 1번에서 만든 위임 속성 필드를 참조하도록 변경한다.
- 서브 클래스에서 일반화 관계 선언을 제거하고 위임 속성 필드에 슈퍼 클래스의 객체를 생성해 대입한다.
- 서브 클래스에서 사용된 슈퍼 클래스의 메서드에도 위임 메서드를 추가한다.
- 컴파일하고 잘 동작하는지 확인한다.
- 친구 클래스로 두어 연관관계로 묶음
피터코드의 상속 규칙
- 자식 클래스와 부모 클래스 사이는 ‘역할 수행is role played by’ 관계가 아니어야 한다.
- 한 클래스의 인스턴스는 다른 서브 클래스의 객체로 변환할 필요가 절대 없어야 한다.
- 자식 클래스가 부모 클래스의 책임을 무시하거나 재정의하지 않고 확장만 수행해야 한다.
- 자식 클래스가 단지 일부 기능을 재사용할 목적으로 유틸리티 역할을 수행하는 클래스를 상속하지 않아야 한다.
- 자식 클래스가 ‘역할role’, ‘트랜잭션transaction’, ‘디바이스device’ 등을 특수화specialization해야 한다.
출처
- Java객체지향 디자인패턴(한빛미디어)