โ๏ธ Java Design-Pattern โ ฉโ ข - Decorator
โ๏ธ Java Design-Pattern โ
ฉโ
ข - Decorator
๐
ใJAVA ์ธ์ด๋ก ๋ฐฐ์ฐ๋ ๋์์ธ ํจํด : ์ฝ๊ฒ ๋ฐฐ์ฐ๋ GoF์ 23๊ฐ์ง ๋์์ธ ํจํดใ
๋ฅผ ์ฝ๊ณ ์ ๋ฆฌํ ๊ธ์ ๋๋ค.
Decorator
ํจํด์ด๋?
- ๊ฐ์ฒด์ ์ ์ ์ฅ์์ ๋ํด ๊ฐ๋ ๋์์ธ ํจํด์ด๋ค.
์์ ํ๋ก๊ทธ๋จ
- ๋ฌธ์์ด ์ฃผ์์ ์ฅ์ํ์ ๋ถ์ฌ ์ถ๋ ฅํ๋ ํ๋ก๊ทธ๋จ์ด๋ค.
Display
ย ํด๋์ค
1
2
3
4
5
6
7
8
9
10
11
public abstract class Display {
public abstract int getColumns();
public abstract int getRows();
public abstract String getRowText(int row);
public void show() {
for (int i = 0; i < getRows(); i++) {
System.out.println(getRowText(i));
}
}
}
- ์ฌ๋ฌ ํ์ผ๋ก ์ด๋ฃจ์ด์ง ๋ฌธ์์ด์ ํ์ํ๋ ์ถ์ ํด๋์ค์ด๋ค.
getColumns
,ยgetRows
๋ ๊ฐ๊ฐ ๋ฌธ์์ด์ ํ๋ ฌ ์๋ฅผ ๊ฐ์ ธ์ค๋ ์ถ์ ๋ฉ์๋์ด๋ค.getRowText
๋ ์ง์ ํ ํ์ ๋ฌธ์์ด์ ๊ฐ์ ธ์ค๋ ์ถ์ ๋ฉ์๋์ด๋ค.show
๋ ๋ชจ๋ ํ์ ํ์ํ๋ ๋ฉ์๋๋ก,ยgetRows
์ยgetRow-Text
๋ผ๋ ์ถ์ ๋ฉ์๋๋ฅผ ์ฌ์ฉํยTemplate Method
ย ํจํด์ผ๋ก ๋์ด ์๋ค.
StringDisplay
ย ํด๋์ค
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
public class StringDisplay extends Display {
private String string;
public StringDisplay(String string) {
this.string = string;
}
@Override
public int getColumns() {
return string.length();
}
@Override
public int getRows() {
return 1;
}
@Override
public String getRowText(int row) {
if (row != 0) {
throw new IndexOutOfBoundsException();
}
return string;
}
}
Display
ย ํด๋์ค์ ์ถ์ ๋ฉ์๋๋ฅผ ๊ตฌํํ๋ ํ์ ํด๋์ค์ด๋ค.string
ย ํ๋๋ ํ์ํ ๋ฌธ์์ด ํ ์ค์ ๋ณด๊ดํ๋ฉฐ,ยgetColumns
๋ ๋ฌธ์์ด ๊ธธ์ด๋ฅผ,ยgetRows
๋ 1์ ๋ฐํํ๋ค.
Border
ย ํด๋์ค
1
2
3
4
5
6
7
public abstract class Border extends Display {
protected Display display;
protected Border(Display display) {
this.display = display;
}
}
display
ย ํ๋๋ ์ด ์ฅ์ํ์ด ๊ฐ์ธ๋ ๋ด์ฉ๋ฌผ์ ์๋ฏธํ๋ค.- ๋ด์ฉ๋ฌผ์ย
Display
ย ํด๋์ค์ ํ์ ํด๋์ค ์ธ์คํด์ค๊ฐ ๋ ๊ฒ์ด๋ค.
SideBorder
ย ํด๋์ค
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class sideBorder extends Border {
private char borderChar;
public sideBorder(Display display, char ch) {
super(display);
this.borderChar = ch;
}
@Override
public int getColumns() {
return 1 + display.getColumns() + 1;
}
@Override
public int getRows() {
return display.getRows();
}
@Override
public String getRowText(int row) {
return borderChar + display.getRowText(row) + borderChar;
}
}
SideBorder
ย ํด๋์ค๋ยBorder
ย ํด๋์ค๋ฅผ ๊ตฌํํ ํ์ ํด๋์ค๋ก, ๋ฌธ์์ด ์์์ยborderChar
๋ก ์ฅ์ํ๋ค.display
ย ํ๋๋ยBorder
ย ํด๋์ค์์ยprotected
๋ก ์ ์ธ ๋์ผ๋ฏ๋ก ํ์ ํด๋์ค์์ ์ฌ์ฉํ ์ ์๋ค.
FullBorder
ย ํด๋์ค
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
public class FullBorder extends Border {
public FullBorder(Display display) {
super(display);
}
@Override
public int getColumns() {
return 1 + display.getColumns() + 1;
}
@Override
public int getRows() {
return 1 + display.getRows() + 1;
}
@Override
public String getRowText(int row) {
if (row == 0) {
return "+" + makeLine('-', display.getColumns()) + "+";
} else if (row == display.getRows() + 1) {
return "+" + makeLine('-', display.getColumns()) + "+";
} else {
return "|" + display.getRowText(row - 1) + "|";
}
}
private String makeLine(char ch, int count) {
StringBuilder line = new StringBuilder();
for (int i = 0; i < count; i++) {
line.append(ch);
}
return line.toString();
}
}
SideBorder
ย ํด๋์ค์ ๋ง์ฐฌ๊ฐ์ง๋กยBorder
์ ํ์ ํด๋์ค ์ค ํ๋์ด๋ฉฐ, ๊ณ ์ ๋ ์ฅ์ ๋ฌธ์๋ก ์ํ์ข์ฐ๋ฅผ ์ฅ์ํ๋ค.makeLine
์ ํด๋์ค ์ธ๋ถ์์ ์ฌ์ฉํ ์ ์๋๋กยprivate
๋ก ๋์ด ์๋ค.
Main
ย ํด๋์ค
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
public class Main {
public static void main(String[] args) {
Display d1 = new StringDisplay("Hello, world.");
Display d2 = new SideBorder(d1, '#');
Display d3 = new StringDisplay(d2);
d1.show();
d2.show();
d3.show();
Display d4 = new SideBorder(
new FullBorder(
new FullBorder(
new SideBorder(
new FullBorder(
new StringDisplay("Hello, world.")
), '*'
)
)
), '/'
);
d4.show();
}
}
- ๋์ ํ
์คํธ์ฉย
Main
ย ํด๋์ค์ด๋ค.
Decorator
ย ํจํด์ ๋ฑ์ฅ์ธ๋ฌผ
Display
ย ํด๋์ค
- ๊ธฐ๋ฅ์ ์ถ๊ฐํ ๋ ํต์ฌ์ด ๋๋ย
Component
ย ์ญํ ์ด๋ค. - ์ฅ์ํ๊ธฐ ์ ์ ์ธํฐํ์ด์คย
API
์ ํด๋นํ๋ค.
StringDisplay
ย ํด๋์ค
Component
์ ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ๋ยConcrete Component
ย ์ญํ ์ ํด๋นํ๋ค.
Border
ย ํด๋์ค
Component
์ ๋์ผํ ์ธํฐํ์ด์ค๋ฅผ ๊ฐ์ง๋ฉฐ ์ฅ์์ยDecorator
ย ์ญํ ์ ํ๋ค.- ๋ํย
Component
๋ฅผ ํ๋๋ก ๊ฐ์ง๊ณ ์๋๋ฐ,ย ์์ ์ด ์ฅ์ํ ๋์์ ์๋ ๊ฒ๊ณผ ๊ฐ๋ค.
SideBorder
,ย FullBorder
ย ํด๋์ค
- ๊ตฌ์ฒด์ ์ธ ์ฅ์์ย
ConcreteDecorator
ย ์ญํ ์ ๋งก์๋ค.
์ฑ ์์ ์ ์ํ๋ ํํธ
ํฌ๊ณผ์ ์ธํฐํ์ด์คย API
- ํด๋น ํจํด์์๋ ์ฅ์ํ๊ณผ ๋ด์ฉ๋ฌผ์ ๋์ผ์ ํ๋ค.ย
Border
ย ํด๋์ค๊ฐยDisplay
ย ํด๋์ค์ ํ์ ํด๋์ค๋ก ๋์ด ์๋ ๋ถ๋ถ์์ ๊ทธ ๋์ผ์๊ฐ ํํ๋์ด ์๋ค.- ์ฆย
Border
ย ํด๋์ค ๋ฐ ๊ทธ ํ์ ํด๋์ค๋ค์ยDisplay
ย ํด๋์ค์ ๊ฐ์ ์ธํฐํ์ด์ค๋ฅผ ๊ฐ๋๋ค. - ์ด ๋ ์ฅ์ํ์ ์ฌ์ฉํด ๋ด์ฉ๋ฌผ์ ๊ฐ์ธ๊ณ ์ธํฐํ์ด์ค๋ ์ ํ ๊ฐ๋ ค์ง์ง ์๋๋ค.ย
getColumns
,ยgetRows
,ยgetRowText
,ยshow
ย ๋ฉ์๋๋ ๊ฐ๋ ค์ง์ง ์๊ณ ๋ค๋ฅธ ํด๋์ค์์ ๋ณผ ์ ์๋ค.
์์์ ์ฌ์ฉํ๋ค.
- ์ฅ์ํ์ ๋ํ ๋ฉ์๋ ํธ์ถ์ ๊ทธ ๋ด์ฉ๋ฌผ๋ก ์์๋๋ค.
- ์์ ํ๋ก๊ทธ๋จ์์๋ย
SideBorder
์ยgetColumns
ย ๋ฉ์๋์์ยdisplay.getColumns
๋ฅผ ํธ์ถํ๊ณ ,ยgetRows
ย ๋ฉ์๋์์ยdisplay.getRows
๋ฅผ ํธ์ถํ๋ค. - ์ฆ ๋ด์ฉ๋ฌผ์ ์์ ํ์ง ์๊ณ ๊ธฐ๋ฅ์ ์ถ๊ฐํ ์๋ ์๋ค.
- ๋ํ ์์์ ํตํด ํด๋์ค ์ฌ์ด๋ฅผ ๋์ ์ผ๋ก ๊ฒฐํฉํ๋๋ฐ, ๊ทธ๋ฌ๋ฏ๋ก ํ๋ ์์ํฌ์ ์์ค๋ฅผ ๋ณ๊ฒฝํ์ง ์๊ณ ๊ฐ์ฒด์ ๊ด๊ณ๋ฅผ ๋ณ๊ฒฝํ ์๋ก์ด ๊ฐ์ฒด๋ฅผ ๋ง๋ค ์ ์๋ค.
java.io
ย ํจํค์ง์ย Decorator
ย ํจํด
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
// 1. ํ์ผ์์ ๋ฐ์ดํฐ๋ฅผ ์ฝ์ด ๋ค์
Reader reader = new FileReader("datafile.txt");
// 2. ํ์ผ์์ ๋ฐ์ดํฐ๋ฅผ ์ฝ์ด ๋ค์ผ ๋ ๋ฒํผ๋ง
Reader reader = new BufferedReader(
new FileReader("datafile.txt")
);
// 3. 2๋ฒ์ ํ ๋ฒํธ ๊ด๋ฆฌ๋ฅผ ์ถ๊ฐ
Reader reader = new LineNumberReader(
new BufferedReader(
new FileReader("datafile.txt")
)
);
// 4. 3๋ฒ์ ํ์ผ์ ์ฝ์ด ๋ค์ด๋ ๋์ ๋คํธ์ํฌ๋ก๋ถํฐ ์ฝ์ด ๋ค์
Socket socket = new Socket(hostName, portNumber);
Reader reader = new LineNumberReader(
new BufferedReader(
new InputStreamReader(
socket.getInputStream();
)
)
);
java.io
ย ์ธ์๋ยjava.swing.border
ย ํจํค์ง์์๋ยDecorator
ย ํจํด์ด ๋ฑ์ฅํ๋ค.
java.nio.file.Files
java.io
ย ํจํค์ง์์ ํด๋น ํจํด์ ์ฌ์ฉํ์ง๋ง ์์ฃผ ์ฌ์ฉํ๋ ๊ธฐ๋ฅ์ ์ผ์ผ์ด ์ฌ๋ฌ ํด๋์ค๋ฅผ ์กฐํฉํ์ง ์์๋ ๊ด๋ จ ๋ฉ์๋๋ฅผ ์ ๊ณตํ๊ณ ์๋ค.
์์๊ณผ ์์์ ๋์ผ์
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
/* 1-1. ์์ - ํ์ ํด๋์ค์ ์์ ํด๋์ค ๋์ผ์ */
class Parent {
void parentMethod() {
// ...
}
}
class Child extends Parent {
// ...
void childMethod() {
// ...
}
}
/* 1-2. ์์ - ํด๋์ค๊ฐ ๋์
*/
Parent obj = new Child();
obj.parentMethod(); // ์บ์คํธ ์์ด ๋์
๊ฐ๋ฅ
Parent obj = new Child();
((Child) obj).childMethod(); // ์บ์คํธ ํ์
/* 2-1. ์์ - ์ฝํ ์ฐ๊ฒฐ */
class Rose {
Violet obj = /* ... */;
void method() {
obj.method();
}
}
class Violet {
void method() {
// ...
}
}
/* 2-2-1. ์์ - ์ถ์ ํด๋์ค ๊ฐํ ์ฐ๊ฒฐ */
abstract class Flower {
abstract void method();
}
class Rose extends Flower {
Violet obj = /* ... */;
@Override
void method() {
obj.method();
}
}
class Violet extends Flower {
@Override
void method() {
// ...
}
}
/* 2-2-2. ์์ - ์ธํฐํ์ด์ค ๊ฐํ ์ฐ๊ฒฐ */
interface Flower {
abstract void method();
}
class Rose implements Flower {
Violet obj = /* ... */;
@Override
void method() {
obj.method();
}
}
class Violet implements Flower() {
@Override
void method() {
// ...
}
}
- ํ์ ํด๋์ค๋ ์์ ํด๋์ค ๋ณ์์ ๋ฐ๋ก ๋์ ํ ์ ์๋ค.
- ๋ฐ๋ฉด ์์ ํด๋์ค๋ฅผ ํ์ ํด๋์ค์ ๋์ ํ๋ ค๋ฉด ์บ์คํธ๊ฐ ํ์ํ๋ค.
- ์์์ ์ฌ์ฉํด ์ธํฐํ์ด์ค๊ฐ ํฌ๊ณผ์ ์ผ๋ก ๋์ด ์์ ๋๋ ์์ ๊ณผ ์์ํ ๊ณณ์ ๋์ผ์ ํ ์ ์๋ค.
This post is licensed under CC BY 4.0 by the author.