- 특정 객체에 기능을 추가하거나 기능을 삭제하기 위해 클래스 내부 변경하거나 하위 클래스를 추가하는 방법
- 이 같은 클래스 차원의 접근 방법은 그 클래스에 속하는 모든 객체에게 영향을 미침
- 우리가 원하는 건 특정 객체에게만 기능을 추가하거나 삭제
- 적합한 해결책은 클래스 차원이 아니라 특정 객체에게만 기능을 추가하거나 삭제
- 객체 차원에서 동적으로 기능을 추가하거나 삭제
- 클래스를 변경시키지 않는 이상 객체 스스로 기능을 추가하거나 삭제할 수는 없다
- 따라서 객체 차원에서 기능을 추가하거나 삭제할 수 있는 유일한 방법
- 다른 객체를 이용해서 원래 객체를 꾸며주는 형태를 취하는 것
- 새로운 기능을 가진 객체가 원래 객체를 꾸며주면서 새로운 기능도 수행해주고 원래 객체가 가진 기능도 수행해주면 마치 새로운 기능이 추가된 것처럼 보이도록 만들 수 있는 것
- 마찬가지로 이렇게 꾸며주고 있던 객체를 없애게 되면 추가되었던 기능이 삭제되는 효과
- 객체들 사이의 참조 연결 고리를 이용해서 객체 기능을 추가하거나 삭제, 특정 객체에 동적으로 기능을 추가
- 사용자는 객체들의 참조 연결 고리가 어떻게 형성되든지 상관 없이 동일한 형태로 기능 수행 요청 가능
- 이 조건이 소스 코드의 수정 없이 동적으로 객체의 기능을 추가하거나 삭제할 수 있는 전제 조건
- 객체 참조 연결 고리에 포함되는 객체들이 모두 동일한 자료형으로 표현
- 이들이 제공하는 인터페이스도 모두 동일
- 각 객체들이 속하는 클래스의 상위에 공통 부모 클래스를 정의
- 상속 관계에 놓여진 클래스들이 모두 동일한 인터페이스를 가지도록 함
* 구현 관련 사항
- 상속 구조 상에 놓인 클래스들은 모두 최상위 클래스의 인터페이스를 지원
- 클라이언트 입장에서 동적으로 객체의 기능이 추가되거나 삭제되더라도 소스코드가 변경되면 안 됨
- 어떤 객체를 참조하든지 동일한 자료형과 인터페이스로 동작
- 최상위 클래스는 최대한 가볍게 유지
- 최상위 클래스는 될 수 있으면 데이터 멤버를 정의하지 않음
- 외부에 제공할 인터페이스도 가능하면 최소로 정의
- 객체에 기능을 추가, 삭제하려면 많은 객체가 생성
- 최상위 클래스에 데이터 멤버가 많이 정의되어 있으면 객체 생성에 따라 불필요하게 메모리 많이 사용
- 중간 클래스로 Decorator 클래스를 두는 문제
- 중간 클래스로 Decorator 클래스를 정의하지 않는다면 하위 클래스들이 곧바로 최상위 클래스를 상속
- 이는 하위 클래스들이 공통으로 관리해야 할 인터페이스나 데이터 멤버들이 있을 경우 문제
- 최상위 클래스는 Decorator 역할을 하는 하위 클래스 뿐만 아니라 일반 하위 클래스도 대표
- Decorator 역할의 하위 클래스들을 위한 공통 인터페이스와 데이터를 매번 정의
- Decorator 는 추상 클래스로 정의
* 유용한 경우
- 다른 객체에게 영향을 주지 않고, 특정 객체에게 동적으로 새로운 기능을 추가하고자 할 때
- 새로운 기능이 추가된 객체와 그렇지 않은 객체를 따로 구분하고 싶지 않을 때
- 특정 객체에게 동적으로 추가된 기능을 삭제하고 싶을 때
- 추가된 기능에 해당하는 객체가 아닌 원래 객체가 가진 기능은 삭제 불가능
- 클래스 상속을 통한 기능 확장이 불가능하거나 어려울 때
- 객체에 기능을 추가하고자 할 때 정적인 상속 관계를 이용하는 것보다 훨씬 유연
- 동일한 기능을 반복하는 것이 간편
- 필요한 만큼 노력을 들이는 접근 방식, 필요할 경우 새로운 클래스들을 조금씩 확장
- 클래스 수는 줄어들 수 있으나 객체의 수는 늘어날 수 있음
댓글