2019. 8. 19. 14:07ㆍ프로그래밍언어/디자인패턴
composite의 의미는 '합성의', '합성물', '혼합 양식'이다. 이를 통해 composite 패턴이 뭔가 합쳐진 형태임을 짐작할 수 있다. 또 composite 패턴의 구성을 보면 일반적인 트리 구조를 하고 있는데, [그림 5-34]처럼 부분-전체의 상속 구조이다. 이와 같이 표현되는 조립 객체를 컴포지트 객체(composite object)라고 한다.
composite 패턴은 사용자가 단일 객체와 복합 객체 모두 동일하게 다루도록 한 것이다. 이런 형태는 재귀적인 구조로서, 마치 파일 구조에서 디렉토리 안에 파일이 존재할 수도 있고, 또 다른 디렉토리(서브 디렉토리)가 존재할 수 있는 것과 같다. 즉 composite 패턴은 그릇(디렉토리)과 내용물(파일)을 동일시해서 재귀적인 구조를 만들기 위한 설계 패턴이다.
컴포지트 패턴을 가장 잘 설명할 수 있는 예제는 파일과 디렉토리 관계이다. 가장 간단하게 파일과 디렉토리를 구현해보자.
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
|
public class File {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public class Directory {
private String name;
private List<File> files;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void addFile(File file) {
if(!files.contains(file)) files.add(file);
else System.out.println("동일한 파일이 존재합니다.");
}
}
|
cs |
위와 같이 구현했다고 생각해보자. 얼핏보면 괜찮은 것 같다. 하지만 만약 디렉토리 밑에 디렉토리를 넣고 싶다면? 어떻게 해야할까? 여기서 생각해보자. 디렉토리 안에는 파일도 들어갈 수 있고 또 다른 디렉토리가 들어갈 수도 있다. 여기서 파일하나가 단수 객체라면 디렉토리는 복수 객체가 될 수 있다. 또한 최상위는 하나의 디렉토리로 이루어지고 그 밑으로 디렉토리 및 파일이 들어간다. 즉, 전체 관계가 하나의 디렉토리이고 그 밑에 부분이 디렉토리 또는 파일이 될 수 있다. 이렇게 단수 혹은 복수를 동일한 인터페이스로 다룰 수 있게 하는 전체-부분관계를 구현할때 가장 유용한 것이 컴포지트 패턴이다.
컴포지트 패턴을 다시 클래스다이어그램으로 나타내면 아래와 같다.
Component - 구체적인 부분, 즉 Leaf 클래스와 전체에 해당하는 Composite 클래스에 공통 인터페이스를 제공한다.
Leaf - 구체적인 부분 클래스로 Composite 객체의 부품으로 설정한다.
Composite - 전체 클래스로 복수 개의 Component를 갖도록 정의한다. 그러므로 복수 개의 Leaf, 심지어 복수 개의 Composite 객체를 부분으로 가질 수 있다.
우리는 맨 처음의 그림과는 다르게 파일 시스템을 설계할 것이다. 파일 시스템은 추상적으로 보면 트리와 같은 구조를 가지고 있다. 즉, Component를 Node로 표현하고 Leaf로 File Composite로 Directory를 표현할 것이다. 바로 구현해보자.
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
|
public abstract class Node {
private String name;
private int depth=0;
public Node(String name) {
this.name=name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getDepth() {
return depth;
}
public void setDepth(int depth) {
this.depth = depth;
}
public abstract int getSize();
public abstract void print();
}
public class File extends Node{
private int size;
public File(String name, int size) {
super(name);
this.size=size;
}
@Override
public int getSize() {
return this.size;
}
@Override
public void print() {
System.out.println("File - "+getName());
}
}
public class Directory extends Node{
private List<Node> nodes = new ArrayList<>();
public Directory(String name) {
super(name);
}
public void addNode(Node node) {
nodes.add(node);
}
public void removeNode(Node node) {
nodes.remove(node);
}
public int getSize() {
int size = nodes.size();
System.out.println("Directory size - "+size);
return size;
}
public void print() {
for(Node node : nodes) {
node.print();
}
}
}
|
cs |
완벽한 구현은 아니지만 파일 시스템을 컴포지트 패턴으로 구현 가능하다라는 정도만 알자!
'프로그래밍언어 > 디자인패턴' 카테고리의 다른 글
디자인패턴 - 어댑터 패턴(Adapter Pattern) (2) | 2019.08.19 |
---|---|
디자인패턴 - 추상 팩토리 패턴(Abstract Factory Pattern) (0) | 2019.08.19 |
디자인패턴 - 팩토리 메소드 패턴(Factory Method pattern) (0) | 2019.08.19 |
디자인패턴 - 데커레이터 패턴(Decorator Pattern) (0) | 2019.08.18 |
디자인패턴 - 커맨드 패턴(Command Pattern),매크로 커맨드 패턴(Macro Command Pattern) (0) | 2019.08.15 |