โ๏ธ Java Design-Pattern 07 - Prototype
โ๏ธ Java Design-Pattern 07 - Prototype
๐
ใJAVA ์ธ์ด๋ก ๋ฐฐ์ฐ๋ ๋์์ธ ํจํด : ์ฝ๊ฒ ๋ฐฐ์ฐ๋ GoF์ 23๊ฐ์ง ๋์์ธ ํจํดใ๋ฅผ ์ฝ๊ณ ์ ๋ฆฌํ ๊ธ์ ๋๋ค.
Prototype ํจํด์ด๋?
- ์ธ์คํด์ค๋ฅผ ์์ฑํ ๋๋ ์ผ๋ฐ์ ์ผ๋กย
newย ํค์๋์ ํจ๊ป ํด๋์ค ๋ช ์ ๋ฐ๋์ ์ง์ ํด์ฃผ์ด์ผ ํ๋ค. - ๊ทธ๋ฐ๋ฐ, ๋ค์๊ณผ ๊ฐ์ ์ํฉ์์ ํด๋์ค ์ด๋ฆ์ ์ง์ ํ์ง ์๊ณ ์ธ์คํด์ค๋ฅผ ์์ฑํ๊ณ ์ถ์ ๋๋ ์๋ค.
โ์ข
๋ฅ๊ฐ ๋๋ฌด ๋ง์ ํด๋์ค๋ก ์ ๋ฆฌํ ์ ์๋ ๊ฒฝ์ฐโ
โํด๋์ค๋ก๋ถํฐ ์ธ์คํด์ค ์์ฑ์ด ์ด๋ ค์ด ๊ฒฝ์ฐโ
โํ๋ ์์ํฌ์ ์์ฑํ๋ ์ธ์คํด์ค๋ฅผ ๋ถ๋ฆฌํ๊ณ ์ถ์ ๊ฒฝ์ฐโ
- ์ฒซ ๋ฒ์งธ๋ ์ทจ๊ธํ ์ค๋ธ์ ํธ ์ข ๋ฅ๊ฐ ๋๋ฌด ๋ง์์ ํ๋ํ๋ ๋ค๋ฅธ ํด๋์ค๋ก ๋ง๋ค๋ฉด ์์ค ํ์ผ์ ๋ง์ด ์์ฑํด์ผ ํ๋ ๊ฒฝ์ฐ์ด๋ค.
- ๋ ๋ฒ์งธ๋ ์์ฑํ๊ณ ์ถ์ ์ธ์คํด์ค๊ฐ ๋ณต์กํ ๊ณผ์ ์ ๊ฑฐ์ณ ๋ง๋ค์ด์ง๋ ๊ฒ์ผ๋ก, ํด๋์ค๋ก๋ถํฐ ๋ง๋ค๊ธฐ ์ด๋ ค์ด ๊ฒฝ์ฐ์ด๋ค.
- ์๋ฅผ ๋ค๋ฉด ๊ทธ๋ํฝ ์๋ํฐ ๋ฑ์ผ๋ก ์ฌ์ฉ์๊ฐ ๋ง์ฐ์ค๋ก ๊ทธ๋ฆฐ ๋ํ์ ๋ํ๋ด๋ ์ธ์คํด์ค ๊ฐ์ด ์ฌ์ฉ์ ์กฐ์์ผ๋ก ๋ง๋ค์ด์ง ์ธ์คํด์ค๊ฐ ํด๋น๋ ์ ์๋ค.
- ์ธ ๋ฒ์งธ๋ ์ธ์คํด์ค๋ฅผ ์์ฑํ๋ ํ๋ ์์ํฌ๋ฅผ ํน์ ํด๋์ค์ ์์กดํ์ง ์๊ฒ ํ๊ณ ์ถ์ ๊ฒฝ์ฐ์ด๋ค.
- ์ด ๊ฒฝ์ฐ์๋ ๋ฏธ๋ฆฌ ์ํ์ด ๋ ์ธ์คํด์ค๋ฅผ ๋ฑ๋กํด๋๊ณ , ๋ฑ๋ก๋ ์ธ์คํด์ค๋ฅผ ๋ณต์ฌํด์ ์ธ์คํด์ค๋ฅผ ์์ฑํ๋ค.
- ์ด์ฒ๋ผย
Prototypeย ํจํด์ ์ํ์ด ๋๋ ์ธ์คํด์ค๋ฅผ ๋ฐํ์ผ๋ก ์๋ก์ด ์ธ์คํด์ค๋ฅผ ๋ง๋ค์ด ๋ด๋ ํจํด์ด๋ค.ย Java์์๋ ๋ณต์ ํ๋ ์กฐ์์ยclone์ด๋ผ๊ณ ๋ถ๋ฅด๋ฉฐ,ยCloneableย ์ธํฐํ์ด์ค์ ํจ๊ป ์ฐ์ธ๋ค.
์์ ํ๋ก๊ทธ๋จ
- ๋ค์ ํ๋ก๊ทธ๋จ์ ๋ฌธ์์ด์ ํ
๋๋ฆฌ๋ก ๊ฐ์ธ์ ํ์ํ๊ฑฐ๋ ๋ฐ์ค์ ๊ทธ์ด ํ์ํ๋ค.

framework์ ํฌํจ๋ยProduct,ยManagerย ํด๋์ค๋ ์ธ์คํด์ค๋ฅผ ๋ณต์ ํ๋ค.Managerย ํด๋์ค๋ยcreateCopy๋ฅผ ํธ์ถํ์ง๋งยProductย ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ ํด๋์ค์ด๊ธฐ๋ง ํ๋ฉด ๊ตฌ์ฒด์ ์ผ๋ก ์ด๋ ํด๋์ค์ ์ธ์คํด์ค๋ฅผ ๋ณต์ ํ ์ง ๊ด์ฌํ์ง ์๋๋ค.MessageBox,ยUnderlinePenย ํด๋์ค๋ ๋ชจ๋ยProductย ํด๋์ค๋ฅผ ๊ตฌํํ ํด๋์ค์ด๋ค.
Productย ์ธํฐํ์ด์ค
1
2
3
4
5
6
package framework;
public interface Product extends Cloneable {
public abstract void use(String s);
public abstract Product createCopy();
}
Clonableย ์ธํฐํ์ด์ค๋ฅผ ์์ํยProductย ์ธํฐํ์ด์ค๋ยclone()์ ํตํด ๋ณต์ ๋ฅผ ๊ฐ๋ฅํ๊ฒ ํ๋ค.use,ยcreateCopyย ์ถ์ ๋ฉ์๋๊ฐ ์ ์ธ๋์ด ์๋ค.
Managerย ํด๋์ค
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package framework;
import java.util.HashMap;
import java.util.Map;
public class Manager {
private Map<String, Product> showcase = new HashMap<>();
public void register(String name, Product prototype) {
showcase.put(name, prototype);
}
public Product create(String prototypeName) {
Product p = showcase.get(prototypeName);
return p.createCopy();
}
}
Productย ์ธํฐํ์ด์ค๋ฅผ ํตํด ์ธ์คํด์ค๋ฅผ ๋ณต์ ํ๋ ํด๋์ค์ด๋ค.Productย ์ธํฐํ์ด์ค๋ยManagerย ํด๋์ค ์์ค ์ฝ๋์๋ ๊ตฌํ ํด๋์ค ๋ช ์ด ํฌํจ๋์ด ์์ง ์์ผ๋ฉฐ, ๊ทธ๋ ๊ธฐ์ ๊ตฌํ ํด๋์ค์ ์์กดํ์ง ์๋๋ค.- ์ด๋ ๊ตฌํ ํด๋์ค์๋ ๋ ๋ฆฝ์ ์ผ๋ก ์์ ํ ์ ์์์ ์๋ฏธํ๋ค.
Manager์๋ยProduct๋ผ๋ ์ธํฐํ์ด์ค๋ง ํฌํจ๋์ด ์๋๋ฐ, ๊ทธ๋ ๊ธฐ์ ์ด ์ธํฐํ์ด์ค๋ง์ดยManagerย ํด๋์ค์ ๋ค๋ฅธ ํด๋์ค๋ฅผ ์ฐ๊ฒฐํ๋ ๋ค๋ฆฌ๊ฐ ๋๋ค.
MessageBoxย ํด๋์ค
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
import framework.Product;
public class MessageBox implements Product {
private char decochar;
public MessageBox(char decochar) {
this.decochar = decochar;
}
@Override
public void use(String s) {
int decolen = 1 + s.length() + 1;
for (int i = 0; i < decolen; i++) {
System.out.print(decochar);
}
System.out.println();
System.out.println(decochar + s + decochar);
for (int i = 0; i < decolen; i++) {
System.out.print(decochar);
}
System.out.println();
}
@Override
public Product createCopy() {
Product p = null;
try {
p = (Product) clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return p;
}
}
- ํด๋น ํด๋์ค์ย
useย ๋ฉ์๋๋ยdecocharย ํ๋๋ก ๋ฌธ์์ด์ ๊ฐ์ผ๋ค. createCopy๋ ์๊ธฐ ์์ ์ ๋ณต์ ํ๋ ๋ฉ์๋์ด๋ค.- ๋ณต์ ํ ๋๋ ์ธ์คํด์ค๊ฐ ๊ฐ์ง ํ๋ ๊ฐ๋ ๊ทธ๋๋ก ์ ์ธ์คํด์ค์ ๋ณต์ฌ๋๋ค.
cloneย ๋ฉ์๋๋ก ๋ณต์ฌํ ์ ์๋ ๊ฒ์ยjava.lang.Cloneableย ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ ํด๋์ค ๋ฟ์ด๋ค.- ๋ง์ฝ ์ด ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ์ง ์๋ ํด๋์ค๊ฐย
cloneย ๋ฉ์๋๋ฅผ ํตํด ๋ณต์ ๋ฅผ ์๋ํ๋ฉดยCloneNotSupportedExceptionย ์์ธ๊ฐ ๋ฐ์ํ ์ ์์ผ๋ฏ๋กยtry ... catch๋ฌธ์ผ๋ก ์์ธ ์ฒ๋ฆฌ๋ฅผ ํด์ฃผ์ด์ผ ํ๋ค. MessageBoxย ํด๋์ค๋ยCloneableย ์ธํฐํ์ด์ค๋ฅผ ํ์ฅํยProductย ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ๊ณ ์๊ธฐ ๋๋ฌธ์ ์์ธ๊ฐ ๋ฐ์ํ์ง ์๋๋ค.Cloneableย ์ธํฐํ์ด์ค๋ ๋จ์ํ ํ์๋ก ์ด์ฉ๋๋ ๋ง์ปค ์ธํฐํ์ด์ค์ผ ๋ฟ, ๋ฐ๋ก ์ ์ธ๋ ๋ฉ์๋๋ ์๋ค.cloneย ๋ฉ์๋๋ ์์ ์ ํด๋์ค ๋๋ ํ์ ํด๋์ค์์๋ง ํธ์ถํ ์ ์์ผ๋ฏ๋ก ๋ค๋ฅธ ํด๋์ค์ ์์ฒญ์ผ๋ก ๋ณต์ ํ ๊ฒฝ์ฐ์๋ยcreateCopy์ ๊ฐ์ ๋ณ๋์ ๋ฉ์๋๋กยclone์ ๊ฐ์ธ์ผ ํ๋ค.
UnderlinePenย ํด๋์ค
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
import framework.Product;
public class UnderlinePen implements Product {
private char ulchar;
public UnderlinePen(char ulchar) {
this.ulchar = ulchar;
}
@Override
public void use(String s) {
int ulen = s.length();
for (int i = 0; i < ulen; i++) {
System.out.print(ulchar);
}
System.out.println();
}
@Override
public Product createCopy() {
Product p = null;
try {
p = (Product) clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return p;
}
}
MessageBoxย ํด๋์ค์ ๊ฑฐ์ ๊ฐ์ ๋์์ ํ๋๋ฐ,ยulcharย ํ๋๊ฐ ๋ฐ์ค๋ก ์ฌ์ฉ๋ ๋ฟ์ด๋ค.
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
import framework.Manager;
import framework.Product;
public class Main {
// ์ ์ธ ๋ฐ ์ด๊ธฐํ
Manager manager = new Manager();
UnderlinePen upen = new UnderlinePen('-');
MessageBox mbox = new MessageBox('*');
MessageBox sbox = new MessageBox('/');
// ๋ฑ๋ก
manager.register("strong message", upen);
manager.register("warning box", mbox);
manager.register("slash box", sbox);
Product p1 = manager.create("strong message");
p1.use("Hello, world!");
Product p2 = manager.create("warning box");
p2.use("Hello, world!");
Product p3 = manager.create("slash box");
p3.use("Hello, world!");
}
Managerย ์ธ์คํด์ค๋ฅผ ๋ง๋ค๊ณ ยProductย ๊ตฌํ์ฒด๋ฅผ ๋ฑ๋กํ์ฌ ์ฌ์ฉํ๋ ๋์ ํ ์คํธ ํด๋์ค์ด๋ค.
Prototypeย ํจํด์ ๋ฑ์ฅ์ธ๋ฌผ
Productย ์ธํฐํ์ด์ค
- ์ธ์คํด์ค๋ฅผ ๋ณต์ฌํ์ฌ ์๋ก์ด ์ธ์คํด์ค๋ฅผ ๋ง๋ค๊ธฐ ์ํ ๋ฉ์๋๋ฅผ ๊ฒฐ์ ํ๋ ์ํย
Prototypeย ์ญํ ์ ํ๋ค.
MessageBox,ย UnderlinePenย ํด๋์ค
- ์ธ์คํด์ค๋ฅผ ๋ณต์ฌํ์ฌ ์๋ก์ด ์ธ์คํด์ค๋ฅผ ๋ง๋๋ ๊ตฌ์ฒด์ ์ธ ์ํ ์ญํ ์ ํ๋ค.
Managerย ํด๋์ค
Productย ์ธํฐํ์ด์ค์ ๋ฉ์๋๋ฅผ ์ด์ฉํด ์๋ก์ด ์ธ์คํด์ค๋ฅผ ๋ง๋๋ ์ด์ฉ์ยClientย ์ญํ ์ ํ๋ค.
์ฑ ์์ ์ ์ํ๋ ํํธ
ํด๋์ค ์ด๋ฆ์ ์๋ฐ์ธ๊ฐ?
- ์์ค ์ฝ๋ ์์ ํด๋์ค ์ด๋ฆ์ ์ฐ๋๊ฒ ์ ๋ฌธ์ ๊ฐ ๋ ๊น?
- ์ฌ๊ธฐ์ ๊ฐ์ฒด์งํฅ ํ๋ก๊ทธ๋๋ฐ์ ๋ชฉํ ์ค ํ๋๊ฐ โ๋ถํ์ผ๋ก์์ ์ฌ์ฌ์ฉโ์ด๋ผ๋ ์ ์ ๋ค์ ํ ๋ฒ ์๊ธฐํ ํ์๊ฐ ์๋ค.
- ์์ค ์ฝ๋ ์์ ํด๋์ค ์ด๋ฆ์ด ์์ผ๋ฉด ํด๋น ํด๋์ค์ ๋ถ๋ฆฌํด์ ์ฌ์ฌ์ฉํ ์ ์๊ฒ ๋๋ค.
- ๋ฌผ๋ก ์์ค ์ฝ๋ ๋ด ํด๋์ค ์ด๋ฆ์ ์์ ํ๋ฉด ๋์ง๋ง ์ฌ๊ธฐ์ ์ฌ์ฌ์ฉ์ด๋ ์์ค ์ฝ๋์ ์์ ์ ๋ฐฐ์ ํ๋ค.
- ์ฆย
.javaย ํ์ผ ์์ดย.classย ํ์ผ๋ง์ผ๋ก ๊ทธ ํด๋์ค๋ฅผ ์ฌ์ฌ์ฉํ ์ ์๋์ง๊ฐ ์ค์ํ๋ค. - ๋ฐ์ ํ๊ฒ ๊ฒฐํฉํด์ผ ํ๋ ํด๋์ค์ ์ด๋ฆ์ด ์์ค ๋ด์์ ์ฌ์ฉ๋๋ ๊ฑด ๋น์ฐํ์ง๋ง ๋ถํ์ผ๋ก ๋ ๋ฆฝ์์ผ์ผ ํ๋ ํด๋์ค ์ด๋ฆ์ด ์์ค ๋ด ์๋ ๊ฒ์ ๋ฌธ์ ๊ฐ ๋๋ค.
cloneย ๋ฉ์๋์ย java.lang.Cloneableย ์ธํฐํ์ด์ค
java.langย ํจํค์ง๋ ์๋ฌต์ ์ผ๋กยimportย ๋์ด ์์ด ๊ฐ๋จํยCloneable๋ก ์ธ ์ ์๋ค.cloneย ๋ฉ์๋๋ยjava.lang.Objectย ํด๋์ค์ ์ ์๋์ด ์๋ค.ยObjectย ํด๋์ค๋ยJavaย ํด๋์ค ๊ณ์ธต์ ์ต์์ ํด๋์ค์ด๋ฏ๋ก ๋ชจ๋ ํด๋์ค์์ยcloneย ๋ฉ์๋๋ฅผ ์์ํ๊ฒ ๋๋ค.cloneย ๋ฉ์๋๋ ์์ ๋ณต์ฌ๋ฅผ ํ๋ค.ยcloneย ๋ฉ์๋์ ๋์์ ํ๋ ๋ด์ฉ์ ๊ทธ๋๋ก ๋ณต์ฌํ๋ ๊ฒ์ด๋ค.- ๊ทธ๋ฌ๋ ํ๋๊ฐ ๊ฐ๋ฆฌํค๋ ์ธ์คํด์ค์ ๋ด์ฉ๊น์ง๋ ๊ณ ๋ คํ์ง ์๋๋ค.
- ๊ฐ๋ น ํ๋์ ๋ฐฐ์ด์ด ์๋ค๊ณ ํ๋ฉด ๊ทธ ๋ฐฐ์ด์ ๋ํ ์ฐธ์กฐ๋ง ๋ณต์ฌ๋๊ณ ๋ฐฐ์ด ์์ ํ๋ํ๋๊ฐ ๋ณต์ฌ๋์ง๋ ์๋๋ค.
- ์ด๋ฌํ ํ๋ ๋ ํ๋์ ๋ณต์ฌ๋ฅผ ์์ ๋ณต์ฌ๋ผ๊ณ ํ๋ค.
- ๋ง์ฝ ์์ ๋ณต์ฌ๋ก ์ถฉ๋ถํ์ง ์๋ค๋ฉดย
cloneย ๋ฉ์๋๋ฅผ ์ค๋ฒ๋ผ์ด๋ํด์ยsuper.clone()์ผ๋ก ์์ ํด๋์ค์ยcloneย ๋ฉ์๋๋ฅผ ํธ์ถํ๋ฉด ๋๋ค.
clone์ ์ฌ์ฉํ๊ธฐ ์ด๋ ต๋ค.
java.lang.Objectย ํด๋์ค์ยcloneย ๋ฉ์๋๊ฐยprotected๋ก ์ง์ ๋์ด ์์ด ์์ ๊ด๊ณ๊ฐ ์๋ ํด๋์ค์ยcloneย ๋ฉ์๋๋ฅผ ํธ์ถํ๊ธฐ๋ ์ด๋ ต๋ค.- ์ค์ ์ธ์คํด์ค๋ฅผ ๋ณต์ ํ๋ ํด๋์ค๋ฅผ ์ค๊ณํ๋ ๊ฒฝ์ฐย
cloneย ๋ฉ์ปค๋์ฆ์ ์์กดํ์ง ์๊ณ ๋ณต์ฌ ์์ฑ์๋ ๋ณต์ฌ ํฉํ ๋ฆฌ๋ฅผ ์ฌ์ฉํ๋ ํธ์ด ์ข๋ค๊ณ ํ๋ค.
This post is licensed under CC BY 4.0 by the author.
