[디자인 패턴] 데코레이터 패턴
구현을 하다보면 자식 클래스에서 부모 클래스의 기능을 기반으로 확장을 할 일이 있다.
기본적으로 오버라이딩은 부모의 행동을 완전히 재정의하는 것이기 때문에, 온전한 확장이라고는 볼 수 없다.
하지만 데코레이터 패턴을 응용하면 더 자연스러운 확장이 가능하다.
사실 그렇게 대단한건 없다. 자식클래스의 메서드에서 상위클래스의 메서드를 호출하고, 추가적으로 자신만의 작업을 수행하면 된다.
예를들어 치킨의 정보를 나타내는 Chicken클래스와 트러플을 넣은 치킨을 나타내는 TruffleChicken 클래스가 있다고 치자.
그리고 각 클래스는 getCost 메서드로 가격을 획득할 수 있다.
트러플치킨은 치킨의 가격에 종속적이라 할 수 있으므로 치킨의 하위클래스로 둘 수도 있을 것 같다?
이 구상을 자바로는 이렇게 구현할 수 있겠다.

이렇게 하면 치킨 클래스에서 치킨의 가격을 바꿔도 자연스럽게 트러플치킨의 가격도 따라서 적용된다.
유의할 점은 꼭 상속과 super를 통해서만 다른 행동을 가져올 필요는 없다는 것이다.
소유관계로 해놓고 메서드를 땡겨써도 되고,
해당 구성요소를 인터페이스나 추상 클래스 등으로 분리해서, 동적으로 받도록 해도 된다.
아래 코드는 소스라는 요소를 분리해서 따로 받고 계산하도록 하는 간단한 예시다.


소스는 대충 이렇게 구현될 수 있겠다.

여기서 Source같은건 추상 구성요소, 저걸 구현한 NoSource같은건 구상 구성요소라 부른다.
그리고 주체가 되는 Chicken 클래스를 데코레이터라 부른다.
데코레이터 패턴은 이렇게 타 클래스의 행동을 감싸서 더하는 것이 핵심이다.
데코레이터란 이름도 무언가 덧붙여 장식하는(decorate) 듯한 모습에서 착안한 것이라 할 수 있겠다.
아무튼 중요한 패턴이다.
줄창 쓰고있는 자바의 입출력 Stream 클래스들만 해도 데코레이터 형식으로 관계를 구성하고 있다.
단점으론 잡다한 클래스들이 너무 많아질수도 있단 점이 있다.
뭐 그래도 죄다 뭉쳐놓는것보단 낫지.
참조
헤드퍼스트 디자인 패턴