Composite Pattern은 단일 객체와 복합객체를 동일하게 처리하기 편하게 만들어줍니다.
그리고 동일한 객체를 반복해서 처리하는 과정에서 재귀적인 구조를 만드는데 도움을 주는 패턴입니다.
이번 예제코드에서는 폴더와 파일 디렉토리 구조를 만드는 예제를 만들어 보겠습니다.
파일과, 폴더를 함께말해서 Entry라고 말하겠습니다.
Entry.java
public abstract class Entry{ public abstract String getName(); public abstract int getSize(); public void printLine(){ printLine(""); } public abstract void printLine(String prefix); public abstract Entry add(Entry entry); public String toString(){ return "/"+getName()+" ("+getSize()+")"; } }
하위 클래스에서 구현하고 있습니다.
File.java(Leaf)
public class File extends Entry{ String name; int size; public File(String name, int size){ this.name = name; this.size = size; }
@Override public String getName() { return name; }
@Override public int getSize() { return size; }
@Override public void printLine(String prefix) { System.out.println(prefix+"/"+this); }
@Override public Entry add(Entry entry) { return null; } }
나는 잘 몰랐는데 Entry class에서 toString을 오버라이딩 해주고있다. printLine에서 문자열과 덧셈 연산에서 this를 불러주면 자동으로 toString()이 호출된 다는 것이다.
this.toString()
toString()
this
모두 동일한 결과가 나온다.
Directory(Composite)
import java.util.ArrayList; import java.util.Iterator; public class Directory extends Entry{ private String name; private int size = 0; private ArrayList documents = new ArrayList(); public Directory(String name){ this.name = name; }
@Override public String getName() { return name; }
@Override public int getSize() { Iterator iterator = documents.iterator(); while(iterator.hasNext()){ Entry entry = (Entry)iterator.next(); size+=entry.getSize(); } return size; }
Directory에서는 File객체가 오든 Doucments객체가 오든 size메소드에서나 printLine에서나 동일하게 처리하는 것을 볼 수 있다.
Main
public class Main { public static void main(String[] args){ try{ Directory rootdir = makeDirectory("root"); Directory bindir = makeDirectory("bin"); Directory tmpdir = makeDirectory("tmp"); Directory usrdir = makeDirectory("usr"); rootdir.add(bindir); rootdir.add(tmpdir); rootdir.add(usrdir); bindir.add(makeFile("vi", 10000)); bindir.add(makeFile("latex", 20000)); rootdir.printLine(); }catch (FileTreatmentException e){ e.printStackTrace(); } }
public static Directory makeDirectory(String name){ return new Directory(name); } public static File makeFile(String name, int size){ return new File(name, size); } }