Decorator Pattern
๊ฐ์ฒด๊ฐ ํ ์ ์๋ ํ๋๋ค์ด ์ ์๋ ์ํ์์, ๊ฐ์ฒด์ ์ถ๊ฐ์ ์ธ ํ๋์ด ์๊ตฌ๋์์ ๋ ๊ฐ์ฒด๋ฅผ ํ์ฅํ๋ ๊ฒ์ด ์๋ ํน์ํ ํ๋์ ํ๋ ๊ฐ์ฒด ๋ํผ์ ๋ฃ์ด์ ์ถ๊ฐ์ ์ธ ํ๋์ ํ ์ ์๋๋ก ํ๋ค.
์ฆ, ๊ธฐ๋ณธ๊ธฐ๋ฅ์ ์ถ๊ฐํ ์ ์๋ ๊ธฐ๋ฅ์ ์ข
๋ฅ๊ฐ ๋ง์ ๊ฒฝ์ฐ ๊ฐ ์ถ๊ฐ ๊ธฐ๋ฅ์ Decorator์ ์ ์ํ์ฌ ์กฐํฉํจ์ผ๋ก์จ ์ถ๊ฐ๊ธฐ๋ฅ์ ๊ตฌํํ ์ ์๋ค.
์๋ฅผ ๋ค์ด ํธ์ฌ ์๋ฆผ์ ๋ณด๋ผ ๋ ํ์ํ ๋ฐ์ดํฐ๋ ์ด๊ธฐ์ ๊ธฐํ๋ ๋ฐ์ดํฐ๋ณด๋ค ๋์ด๋ ์๊ฐ ์๋ค. A,B,C ํธ์ฌ๋ฅผ ๋ณด๋ผ ๋ ๊ธฐ๋ณธ์ ์ธ ํ์ ๋น์ทํ์ง๋ง, ๊ฐ๊ฐ ๋ณด๋ด์ผ ํ ๋ฐ์ดํฐ๋ ๋ด๋ถ์ ์ผ๋ก ์กฐ๊ธ์ฉ ๋ค๋ฅด๊ธฐ ๋ง๋ จ์ด๋ค. ์๋ฅผ ๋ค์ด, ์ด๋ค ํธ์ฌ๋ app scheme์ ๋ณด๋ด์ผํ๊ณ , ์ด๋ค ํธ์ฌ๋ webview๋ฅผ ๋์ธ url์ ๋ณด๋ด์ผํ๋ ๊ทธ๋ฐ ๊ฒฝ์ฐ์ด๋ค.
์ด๋ ๊ฒ ๊ธฐ๋ณธ์ ์ผ๋ก ์ ํด์ง ํ์ ์กด์ฌํ์ง๋ง, ์ถ๊ฐ์ ์ธ ๊ธฐ๋ฅ์ด ๋ง์์ง๊ณ ์ด๋ฅผ ์กฐํฉํด์ผ ํ ๊ฒฝ์ฐ ๋ฐ์ฝ๋ ์ดํฐ ํจํด์ ์ฐ๋ฉด ๋์ ์ผ๋ก ์ฌ๋ฌ ์กฐํฉ์ ๊ตฌํํ ์ ์๋ค.
๋ฌผ๋ก , ์์์ ์ด์ฉํด์ ๋ค์ํ ๊ธฐ๋ฅ, ์กฐํฉ์ ๊ฐ์ง ํด๋์ค๋ค์ ๊ตฌํํ ์ ์๋ค. ๋ค๋ง ์์์ ์ ์ ์ด๋ค. ํ๋ฒ ๊ตฌํ๋๋ฉด ๋ฐํ์์ ํ๋์ ๋ณ๊ฒฝํ ์ ์๋ค.
๋ฐ์ฝ๋ ์ดํฐ ํจํด์์๋ ์ด๋ฌํ ์ฌํญ์ ๊ทน๋ณตํ๊ธฐ ์ํด, ์์ ๋์ ์งํฉ ๊ด๊ณ
๋๋ ๊ตฌ์ฑ
์ ํ์ฉํ๋ค. ์ด๋ฌํ ์ ๊ทผ๋ฐฉ์์ ์ฌ์ฉํ๋ฉด ์ฐ๊ฒฐ๋ ๋์ฐ๋ฏธ ๊ฐ์ฒด๋ฅผ ๋ค๋ฅธ ๊ฐ์ฒด๋ก ์ฝ๊ฒ ๋์ฒดํ์ฌ ๋ฐํ์ ๋์ ์ปจํ
์ด๋์ ํ๋์ ๋ณ๊ฒฝํ ์ ์๋ค. ๊ฐ์ฒด๋ ์ฌ๋ฌ ํด๋์ค์ ํ๋์ ์ฌ์ฉํ ์ ์๊ณ , ์ฌ๋ฌ ๊ฐ์ฒด์ ๋ํ ์ฐธ์กฐ๊ฐ ์์ผ๋ฉฐ ์ด ๊ฐ์ฒด๋ค์ ๋ชจ๋ ์ข
๋ฅ์ ์์
์ ์์ํ๋ค.
์ด๋ ๊ฒ ๊ตฌ์ฑํ๊ณ ๋์ email -> facebook -> slack์ผ๋ก ์๋ฆผ์ ๋ณด๋ด์ผ ํ๋ค๋ฉด ํด๋ผ์ด์ธํธ๋ ๋ค์๊ณผ ๊ฐ์ด ๊ตฌ์ฑํ๋ฉด ๋๋ค.
1
2
3
4
5
6
7
8
| stack = new Notifier();
if (facebookEnabled) {
stack = new FacebookDecorator(stack);
}
if (slackEnabled) {
stack = new SlackDecorator(stack);
}
app.setNotifier(stack);
|
๊ตฌ์กฐ
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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
| /**
* Base Component interface ๋ ๋ฐ์ฝ๋ ์ดํฐ์ ์ํด ๋ฌ๋ผ์ง ์ ์๋ ํ๋์ ์ ์ํ๋ค.
*/
interface component {
operation(): string;
}
/**
* Concrete Component ๋ Component interface์ ๊ธฐ๋ณธ ํ๋์ ์ ์ํ๋ค.
* ํด๋น ํด๋์ค๋ ๋ค์ํ ๋ณํ์ด ์ผ์ด๋ ์ ์๋ค.
*/
class ConcreteComponent implements Component {
public operation(): string {
return "ConcreteComponent";
}
}
/**
* The base Decorator class follows the same interface as the other components.
* The primary purpose of this class is to define the wrapping interface for all
* concrete decorators. The default implementation of the wrapping code might
* include a field for storing a wrapped component and the means to initialize
* it.
*/
class Decorator implements Component {
protected component: Component;
constructor(component: Component) {
this.component = component;
}
/**
* The Decorator delegates all work to the wrapped component.
*/
public operation(): string {
return this.component.operation();
}
}
/**
* Concrete Decorators call the wrapped object and alter its result in some way.
*/
class ConcreteDecoratorA extends Decorator {
/**
* Decorators may call parent implementation of the operation, instead of
* calling the wrapped object directly. This approach simplifies extension
* of decorator classes.
*/
public operation(): string {
return `ConcreteDecoratorA(${super.operation()})`;
}
}
/**
* Decorators can execute their behavior either before or after the call to a
* wrapped object.
*/
class ConcreteDecoratorB extends Decorator {
public operation(): string {
return `ConcreteDecoratorB(${super.operation()})`;
}
}
/**
* The client code works with all objects using the Component interface. This
* way it can stay independent of the concrete classes of components it works
* with.
*/
function clientCode(component: Component) {
// ...
console.log(`RESULT: ${component.operation()}`);
// ...
}
/**
* This way the client code can support both simple components...
*/
const simple = new ConcreteComponent();
console.log("Client: I've got a simple component:");
clientCode(simple);
console.log("");
/**
* ...as well as decorated ones.
*
* Note how decorators can wrap not only simple components but the other
* decorators as well.
*/
const decorator1 = new ConcreteDecoratorA(simple);
const decorator2 = new ConcreteDecoratorB(decorator1);
console.log("Client: Now I've got a decorated component:");
clientCode(decorator2);
|
์ ์ฉ
์์์ ์ฌ์ฉํ์ฌ ๊ฐ์ฒด์ ํ๋์ ํ์ฅํ๋ ๊ฒ์ด ์ด์ํ๊ฑฐ๋ ๋ถ๊ฐ๋ฅํ ๋ ์ฌ์ฉํ๋ฉด ์ข๋ค. ์๋ฅผ ๋ค์ด ํ์๋ก ํ๋ ์ถ๊ฐ๊ธฐ๋ฅ์ด ํ๊ฐ์ฉ ๋์ด๊ฐ ๋๋ง๋ค 2๋ฐฐ๋ก ์์ํด๋์ค๋ฅผ ๊ตฌํํด์ผ ํ๋ค๊ฑฐ๋ ๋ถํ์ํ ์์์ ํ ๋ ๋ฐ์ฝ๋ ์ดํฐ ํจํด์ ์ฌ์ฉํ๋ฉด ์ฝ๋๊ฐ ๊น๋ํด์ง๋ค.
์ด๋ค ๊ฐ์ฒด๋ฅผ ์ฌ์ฉํ๋ ์ฝ๋๋ฅผ ๋ณ๊ฒฝํ์ง ์์ผ๋ฉด์ ์ถ๊ฐ์ ์ธ ํ๋์ ๊ฐ์ฒด์ ํ ๋นํ ์ ์์ด์ผ ํ ๋ ์ฌ์ฉํ๋ค.