데코레이트 패턴 (Decorator Pattern)
JAVA/Design Pattern

데코레이트 패턴 (Decorator Pattern)

반응형

데코레이트 패턴은 기본 기능에 추가할 수 있는 기능의 종류가 
많은 경우에 각 추가 기능을 Decorator 클래스로 정의한 후 필요한 Decorator 객체를 조합함으로써

추가 기능을 설계하는 방식이다.

문제가 되는 예를 확인해보자.

만약 

음식을 할 때, 준비를 해는 클래스 ReadyDish가 있다고 해보자.

생선 음식을 준비해야할 때는 ReadyDish 클래스에서 하는 ready() 메소드가 필요하며, 생선클래스를 위한 메소드 readyForFish()메소드가 필요하다.

그럴경우 기본적인 기능은 ReadyDish 클래스에 정의하고
추가적인 기능은 다음과 같이 하위클래스로서 상속받아서 진행할 수도 있다.



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package decorator;
 
public class ReadyDish {
    public void ready() {
        System.out.println("ready");
    }
}
 
 
package decorator;
 
public class RedayForFish extends ReadyDish {
    @Override
    public void ready() {
        super.ready();
        readyForFish();
    }
    
    public void readyForFish() {
        System.out.println("ready For Fish");
    }
}
cs




그런데 이런건 문제의 소지가 있다.

만약 고기요리 클래스가 늘어났을경우에는 RedayForMeat 클래스를 만들어야 하고 
그에 상응하는 readyForMeat() 메소드도 만들어야한다. 

이는 되게 불편하기에 데코레이터 패턴을 사용하여 정리하여야 한다.


1. 기본적으로 음식 가공을 준비하는 ready메소드를 제공하는 추상클래스 dish 생성한다.
2. 기본음식 준비를 하는 readyDish 클래스를 dish 클래스를 상속받아 구현한다.
3. 추가적인 생선요리, 고기요리 등에 사용될 클래스들을 따로 생성하고 기본적인 음식 준비를 위한 기능을 할 수 있도록 해주는 ReadyDishDecorator 클래스를 생성한다.





1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
package decorator;
 
public abstract class Dish {
    public abstract void ready();
}
 
package decorator;
 
public class ReadyDish extends Dish {
    @Override
    public void ready() {
        System.out.println("ready");
    }
}
 
package decorator;
 
public abstract class DishDecorator extends Dish {
    private Dish decoratedDish;
    
    public DishDecorator(Dish decoratedDish) {
        this.decoratedDish = decoratedDish;
    }
    
    @Override
    public void ready() {
        decoratedDish.ready();
    }
}
 
package decorator;
 
public class ReadyDishForFish extends DishDecorator {
 
    public ReadyDishForFish(Dish decoratedDish) {
        super(decoratedDish);
    }
    
    public void ready() {
        super.ready();
        readyForFish();
    }
    
    public void readyForFish() {
        System.out.println("ready For fish");
    }
 
}
 
package decorator;
 
public class ReadyDishForMeat extends DishDecorator {
 
    public ReadyDishForMeat(Dish decoratedDish) {
        super(decoratedDish);
    }
    
    public void ready() {
        super.ready();
        readyForMeat();
    }
    
    public void readyForMeat() {
        System.out.println("ready For meat");
    }
 
}
cs



이런 방식의 설계를 이용하면 추가 기능 조합별로 별도의 클래스를 구현하는 대신 
각 추가 기능에 해당하는 클래스의 객체를 조합해 추가 기능을 조합을 구현할 수 있다.

예를 들어보면 
생선도 준비하고 고기 음식을 준비해야 한다 했을 때
다음과 같이 하면 여러가지 항목들을 조합하여 필요에 따라 여기저기 합쳐서 사용할 수 있다.



1
2
3
4
5
6
7
Dish dishForFishMeat = new ReadyDishForMeat(new ReadyDishForFish(new ReadyDish()));
dishForFishMeat.ready();
 
// 출력결과 
ready
ready For fish
ready For meat
cs



이와 같은 설계는 추가 기능이 많을 수록 효과가 커서
여러가지 기능들이 자주 조합되어야 할때 섞여서 사용되어야 할때 사용하면 좋다.



반응형