[디자인패턴] Decorator Pattern, 데코레이터 패턴
배경(Why)
도서관 소식을 유저에게 알리는 프로그램이 있다.
초기 요구사항에는 전달방식이 이메일 하나만 있었다.
그리고 전달방식에 Facebook, Slack이 추가되었다.
subclass로 둬 추가 요건을 반영했다.
그러자 한 사용자가 여러 Notifier를 가질 수 있다는 요건이 추가되었다.
모든 조합을 subclass로 뒀다... 너무 복잡해지고 한 클래스에 많은 책임이 생겨 SRP를 위배한다! 어떻게 개선할 수 있을까?
How
추가요건을 상속
으로 해결하려고 하다보니 이런 문제가 발생했다. 상속은 다음과 같은 문제가 있다.
- static하다. 따라서, object의 행위를 runtime에 바꿀 수 없다. 만약 그렇게 하려면 아예 object를 다른 subclass로 바꿔야한다.
- 한 행위에 대해 여러 클래스를 상속받을 수 없다.
이를 Composition
또는 Aggregation
으로 해결하고자 한다!
- Composition: Wrapper(Person)과 Wrapped(Heart)가 같은 생명주기를 갖는다.
// 전체 생성 Person person = new Person(); // 전체 생성자 내 Person() { heart = new Heart(); }
- Aggregation: 각각 다른 생명주기를 갖는다.
Heart heart = new Heart(); Person person = new Person(heart);
이를 이용해 다음과 같이 구현하다고 생각해보자
- Wrapper는 Wrapped와 같은 Interface를 구현한다.
- Wrapper가 그 Interface를 멤버변수로 갖는다.
이렇게 구현한다면,
- Wrapped class인 Notifier를 runtime에 갈아끼울 수 있게된다!
- 클래스들이 하나씩 참조를 하게 되면(chain) 위임(delegate)을 통해 여러 클래스의 행위를 사용할 수 있다.
What
위와 같이 동작하는 Decorator Pattern이란,
주어진 상황 및 용도에 따라 어떤 객체에 책임을 덧붙이는 패턴이다.
- Component: Wrapper, Wrapped class가 구현할 Common Interface
- Concrete Component: Wrap 될 기본기능
- Base Decorator: Wrapped class를 참조한다. 그 Wrapped class의 타입을 Component로 둬 Concrete Component, Decorators를 참조할 수 있게된다. 또, 모든 들어오는 연산을 Wrapped Object에 위임한다.
- Concrete Decorators: Component에 추가할 행위를 정의
언제 쓸까?(When)
- extra 행위를 런타임에 구성해야 할 때
비즈니스 로직을 계층화해 여러 조합의 로직을 런타임에 구성할 수 있다. - 상속으로 문제를 해결할 수 없는 상황
final keyword 사용 등
Pros
- SRP을 만족한다.
- 객체의 책임을 런타임에 붙이고, 떼어낸다.
- 여러 행위를 조합할 수 있다.
Con
한 번 구성하면 Wrapped를 없애기 쉽지 않다!
실제 사용케이스
Java I/O에서 사용된다.
serialized Java objects in a Gzipped file가 있고 빠른 속도로 읽어와야하는 상황이라고 가정하자.
- inputstream을 연다.
FileInputStream fis = new FileInputStream("/objects.gz");
- 빠르게 하기 위해 버퍼를 사용한다.
BufferedInputStream bis = new BufferedInputStream(fis);
- gzipped 파일을 사용하기 때문에, 이를 unzip한다.
GzipInputStream gis = new GzipInputStream(bis);
- unserialize 한다.
ObjectInputStream ois = new ObjectInputStream(gis);
이렇게 책임을 하나씩 붙이고 다음과 같이 사용한다!
SomeObject someObject = (SomeObject) ois.readObject();
상황에 맞게 자유롭게 stream을 데코레이트하는 것을 확인할 수 있다!
ref
https://refactoring.guru/design-patterns/decorator
https://www.google.com/url?sa=i&url=https%3A%2F%2Fen.wikipedia.org%2Fwiki%2FDecorator_pattern&psig=AOvVaw1UpIvHdtHYw7QbovWyFivp&ust=1617199397826000&source=images&cd=vfe&ved=0CAkQjhxqFwoTCNCbp7GX2O8CFQAAAAAdAAAAABAP
https://stackoverflow.com/questions/6366385/use-cases-and-examples-of-gof-decorator-pattern-for-io
Author And Source
이 문제에 관하여([디자인패턴] Decorator Pattern, 데코레이터 패턴), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@cchloe2311/ㄷㄹㅋㅇㅌ저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)