반응형
데코레이터 패턴
주어진 상황 및 용도에 따라 객체에 대한 책임을 덧붙이는 패턴
기능 확장이 필요할 때 서브클래싱 대신 쓸 수 있는 대안
자바는 다중 상속을 지원하지 않기 때문에 추가해야 할 기능의 종류가 많은 경우 데코레이터 패턴을 사용할 수 있다.
데코레이터 클래스와 데코레이터를 적용할 클래스는 합성 관계를 통해 표현된다.
합성(has-a) 관계
- 생성자에서 필드에 대한 객체를 생성하는 경우
- 전체 객체가 없어지면 부분 객체도 없어진다.
- 상속에 의해 코드를 재사용하는 것 대신, 객체의 기능(인터페이스)를 호출하는 방식을 통해 재사용
전체 코드
public class Decorator {
public static void main(String[] args){
Wallet decoratedWallet = new ColorDecorator(
new ZipperDecorator(new SimpleWallet())
);
decoratedWallet.custom();
}
}
interface Wallet{
void custom();
}
class SimpleWallet implements Wallet{
@Override
public void custom() {
System.out.println("My Wallet");
}
}
class WalletDecorator implements Wallet{
private Wallet decoratedWallet;
public WalletDecorator(Wallet decoratedWallet){
this.decoratedWallet = decoratedWallet;
}
@Override
public void custom() {
decoratedWallet.custom();
}
}
class ColorDecorator extends WalletDecorator{
ColorDecorator(Wallet decoratedWallet){
super(decoratedWallet);
}
@Override
public void custom() {
super.custom();
System.out.println("Color My wallet");
}
}
class ZipperDecorator extends WalletDecorator{
ZipperDecorator(Wallet decoratedWallet){
super(decoratedWallet);
}
@Override
public void custom() {
super.custom();
System.out.println("Zip My wallet");
}
}
코드로 보면 이해하기 더 쉬운데, 데코레이터 패턴을 적용하지 않고 Color+Zipper를 모두 데코레이트 해야 한다면 ColorZipper 클래스를 하나 더 생성해야 한다.
기능이 더 많아지면 클래스 경우의 수는 더 많아지게 된다. 이렇게 기능에 따라 각각 클래스를 생성하지 않아도 원하는 기능만 추가할 수 있게 해준다.
또한 상속 관계가 아닌 합성 관계를 사용하기 때문에 클래스 간의 결합도를 낮춰준다.
참고
https://ko.wikipedia.org/wiki/데코레이터_패턴
https://gmlwjd9405.github.io/2018/07/09/decorator-pattern.html
https://mantaray.tistory.com/69
반응형
'Clean Code' 카테고리의 다른 글
[Design Pattern] 구조 패턴 - 어댑터 패턴 (0) | 2022.03.08 |
---|---|
[Design Pattern] 구조 패턴 - 컴포지트 패턴 (0) | 2022.03.06 |
[Design Pattern] 생성 패턴 - 싱글톤 패턴 (0) | 2022.03.03 |
[Design Pattern] 생성 패턴 - 프로토 타입 패턴 (0) | 2022.03.03 |
[Design Pattern] 생성 패턴 - 팩토리 메소드 패턴, 추상 팩토리 패턴 (0) | 2022.03.01 |