디자인패턴의 단골 패턴 중 하나인 컴포지트(Composite) 패턴입니다.
컴포지트 패턴은 간단히 말해서
추상적인 상위 클래스 하나를 만들고,
그 클래스를 상속받는 다양한 자식 클래스들을 만들어
결국, 다양한 자식 클래스들을 마치 같은 종류의 클래스 다루듯이 동일시해서 사용하겠다는 패턴입니다.
이 컴포지트 패턴은 나중에 커맨드(Command) 패턴이나 방문자(Visitor) 패턴, 데코레이터(Decorator) 패턴 등에
응용되서 사용되어질 수 있습니다. 상당히 유용한 패턴인거죠 !!
그리고 여기서 더 나아가 트리 구조와 같은 재귀적인(Recursive) 구조를 만들기 위해서도 유용하게 쓰입니다.
트리 구조의 가장 모범적인 예제로는 '파일 구조'가 있습니다.
각종 폴더와 파일들이 있으며, 특정 폴더 아래에는 또 다른 폴더들과 파일들이 존재하죠.
이를 컴포지트 패턴을 이용해서 표현해보도록 하겠습니다.
컴포지트 패턴은 다음과 같이 Component, Leaf, Composite 로 구성되어집니다.
public abstract class Component
{public abstract Component add(Component cp);
public abstract void remove(Component cp);
...}
public class Leaf extends Component
{...
}
public class Composite extends Component
{private ArrayList arrChildren = new ArrayList();
}
public Component add(Component cp);
public abstract void remove(Component cp);
...
여기서 Leaf 역할은 File 클래스가, Composite 역할은 Folder 클래스가 맡게 됩니다.
대략적인 소스는 다음과 같습니다.
Component.java
01.
package
snowdeer.pattern.composite;
02.
03.
import
java.io.IOException;
04.
05.
public
abstract
class
Component
06.
{
07.
public
abstract
String getName();
08.
public
abstract
int
getSize();
09.
10.
public
Component add(Component component)
throws
Exception
11.
{
12.
throw
new
IOException();
13.
}
14.
15.
public
void
printList()
16.
{
17.
printList(
""
);
18.
}
19.
20.
protected
abstract
void
printList(String strPrefix);
21.
22.
public
String toString()
23.
{
24.
return
getName() +
"("
+ getSize() +
")"
;
25.
}
26.
}
File.java
01.
package
snowdeer.pattern.composite;
02.
03.
import
android.util.Log;
04.
05.
public
class
File
extends
Component
06.
{
07.
private
String m_strName;
08.
private
int
m_nSize;
09.
10.
public
File(String strName,
int
nSize)
11.
{
12.
m_strName = strName;
13.
m_nSize = nSize;
14.
}
15.
16.
@Override
17.
public
String getName()
18.
{
19.
return
m_strName;
20.
}
21.
22.
@Override
23.
public
int
getSize()
24.
{
25.
return
m_nSize;
26.
}
27.
28.
@Override
29.
protected
void
printList(String strPrefix)
30.
{
31.
Log.i(
"Composite Pattern"
, strPrefix +
"/"
+
this
);
32.
}
33.
}
Folder.java
01.
package
snowdeer.pattern.composite;
02.
03.
import
java.util.ArrayList;
04.
import
java.util.Iterator;
05.
06.
import
android.util.Log;
07.
08.
public
class
Folder<e>
extends
Component
09.
{
10.
private
String m_strName;
11.
private
ArrayList arrFolders =
new
ArrayList();
12.
13.
public
Folder(String strName)
14.
{
15.
m_strName = strName;
16.
}
17.
18.
@Override
19.
public
String getName()
20.
{
21.
return
m_strName;
22.
}
23.
24.
@Override
25.
public
int
getSize()
26.
{
27.
int
_size = 0;
28.
Iterator<folder> it = arrFolders.iterator();
29.
while
(it.hasNext() ==
true
)
30.
{
31.
Component cp = (Component)it.next();
32.
_size = _size + cp.getSize();
33.
}
34.
35.
return
_size;
36.
}
37.
38.
@Override
39.
public
Component add(Component component)
40.
{
41.
arrFolders.add(component);
42.
43.
return
this
;
44.
}
45.
46.
@Override
47.
protected
void
printList(String strPrefix)
48.
{
49.
Log.i(
"Composite Pattern"
, strPrefix +
"/"
+
this
);
50.
51.
Iterator<folder> it = arrFolders.iterator();
52.
while
(it.hasNext() ==
true
)
53.
{
54.
Component cp = (Component)it.next();
55.
cp.printList(strPrefix +
"/"
+ m_strName);
56.
}
57.
}
58.
}
59.
</folder></folder></e>
그리고 이렇게 만든 클래스를 활용해보는 테스트 예제 코드는 다음과 같습니다.
01.
package
snowdeer.pattern.activity;
02.
03.
import
snowdeer.pattern.composite.File;
04.
import
snowdeer.pattern.composite.Folder;
05.
import
android.app.Activity;
06.
import
android.os.Bundle;
07.
import
android.util.Log;
08.
09.
public
class
ActMain
extends
Activity
10.
{
11.
/** Called when the activity is first created. */
12.
@Override
13.
public
void
onCreate(Bundle savedInstanceState)
14.
{
15.
super
.onCreate(savedInstanceState);
16.
setContentView(R.layout.main);
17.
18.
try
19.
{
20.
Log.i(
"Composite Pattern"
,
"Creating folders and files...."
);
21.
22.
Folder rootFolder =
new
Folder(
"root"
);
23.
Folder folder_1 =
new
Folder(
"folder_1"
);
24.
Folder folder_2 =
new
Folder(
"folder_2"
);
25.
Folder folder_3 =
new
Folder(
"folder_3"
);
26.
27.
rootFolder.add(folder_1);
28.
rootFolder.add(folder_2);
29.
rootFolder.add(folder_3);
30.
31.
folder_1.add(
new
File(
"file_1"
, 100));
32.
folder_2.add(
new
File(
"file_2"
, 100));
33.
folder_2.add(
new
File(
"file_3"
, 200));
34.
35.
Folder subFolder_1 =
new
Folder(
"subFolder_1"
);
36.
Folder subFolder_2 =
new
Folder(
"subFolder_2"
);
37.
38.
folder_1.add(subFolder_1);
39.
folder_1.add(subFolder_2);
40.
41.
subFolder_1.add(
new
File(
"sub_File_1"
, 100));
42.
subFolder_1.add(
new
File(
"sub_File_2"
, 100));
43.
subFolder_1.add(
new
File(
"sub_File_3"
, 100));
44.
45.
rootFolder.printList();
46.
}
47.
catch
(Exception e)
48.
{
49.
e.printStackTrace();
50.
}
51.
}
52.
}
'디자인 패턴' 카테고리의 다른 글
패턴의 종류 (0) | 2014.09.11 |
---|---|
디자인패턴 (0) | 2014.09.11 |
[디자인패턴]싱글톤(Singleton)패턴 (0) | 2013.05.27 |