컴포지트 패턴을 Java 인터페이스로 구현하기
컴포지트 패턴은 객체 지향 디자인 패턴 중 하나로, 객체들을 트리 구조로 구성하여 부분-전체 계층을 나타내는 패턴입니다. 이 패턴은 객체들의 구성을 통해 다양한 작업을 수행할 수 있게 되며, 대표적인 예로는 GUI 화면 구성 및 계층 구조를 활용한 파일 시스템 등이 있습니다. 이번 글에서는 Java 언어에서 컴포지트 패턴을 구현하는 방법에 대해 알아보겠습니다.
컴포지트 패턴: 개념과 구현 방법
컴포지트 패턴은 객체들을 트리 구조로 구성합니다. 이 구조에서 각 객체는 자기 자신을 나타내는 Leaf 객체와 부모 객체와 자식 객체를 가지는 Composite 객체로 구분됩니다. Composite 객체는 자식 객체를 추가, 제거, 순회하는 메서드를 가지며, 이를 통해 트리 구조를 유지합니다.
컴포지트 패턴을 구현하는 방법은 크게 두 가지가 있습니다. 첫 번째 방법은 객체들이 인터페이스를 공유하는 것입니다. 이 경우 Leaf 객체와 Composite 객체 모두가 같은 인터페이스를 구현하게 되며, 이를 통해 클라이언트 코드에서는 객체의 타입을 신경쓰지 않고도 일관된 방식으로 객체를 다룰 수 있습니다.
Java 인터페이스를 활용한 컴포지트 패턴 구현
Java 언어에서 컴포지트 패턴을 구현할 때에는 인터페이스를 활용하는 것이 좋습니다. 이를 통해 객체들이 공통된 메서드를 가지고 있기 때문에, 클라이언트 코드에서는 객체의 타입을 신경쓰지 않고도 일관된 방식으로 객체를 다룰 수 있습니다.
예를 들어, 파일 시스템을 구현할 때에는 File 객체와 Directory 객체를 구현합니다. File 객체는 Leaf 객체로, Directory 객체는 Composite 객체로 구현합니다. 이 때, File과 Directory는 모두 FileSystemObject 인터페이스를 구현하게 됩니다.
public interface FileSystemObject {
String getName();
void print();
}
위의 인터페이스에서는 getName()과 print() 메서드를 정의하고 있습니다. getName()은 객체의 이름을 반환하는 메서드이며, print()는 객체를 출력하는 메서드입니다. 이제 Leaf 객체와 Composite 객체 모두가 이 인터페이스를 구현하게 됩니다.
실제 예제를 통해 Java에서의 컴포지트 패턴 적용 방법 익히기
다음은 실제로 Java에서 컴포지트 패턴을 활용한 예제입니다. 이 예제에서는 음식 메뉴를 구현합니다. 음식 메뉴는 각각의 요소로서 MenuItem과 Menu로 구분되며, MenuItem은 Leaf 객체로, Menu는 Composite 객체로 구현됩니다.
public interface MenuComponent {
String getName();
String getDescription();
double getPrice();
void print();
}
public class MenuItem implements MenuComponent {
private String name;
private String description;
private double price;
public MenuItem(String name, String description, double price) {
this.name = name;
this.description = description;
this.price = price;
}
public String getName() {
return name;
}
public String getDescription() {
return description;
}
public double getPrice() {
return price;
}
public void print() {
System.out.println(getName() + " (" + getDescription() + "): " + getPrice());
}
}
public class Menu implements MenuComponent {
private List components = new ArrayList();
private String name;
private String description;
public Menu(String name, String description) {
this.name = name;
this.description = description;
}
public void add(MenuComponent component) {
components.add(component);
}
public void remove(MenuComponent component) {
components.remove(component);
}
public MenuComponent getChild(int i) {
return components.get(i);
}
public String getName() {
return name;
}
public String getDescription() {
return description;
}
public void print() {
System.out.println("n" + getName() + " (" + getDescription() + ")n------------------------");
for (MenuComponent component : components) {
component.print();
}
}
}
위의 코드에서는 MenuComponent 인터페이스를 정의하고 있습니다. 이 인터페이스에서는 getName(), getDescription(), getPrice(), print() 메서드를 정의하고 있습니다. MenuItem은 이 인터페이스를 구현하고 있으며, Menu는 Composite 객체로서 이 인터페이스를 구현하고 있습니다.
Menu 객체는 List를 가지고 있으며, add(), remove(), getChild() 메서드를 통해 자식 객체를 추가, 제거, 순회할 수 있습니다. print() 메서드에서는 해당 객체의 정보와 하위 객체의 정보를 출력합니다.
이제 Menu와 MenuItem 객체를 생성하여 사용할 수 있습니다.
MenuComponent pancakeHouseMenu = new Menu("Pancake House Menu", "Breakfast");
MenuComponent dinerMenu = new Menu("Diner Menu", "Lunch");
MenuComponent allMenus = new Menu("All Menus", "All menus combined");
allMenus.add(pancakeHouseMenu);
allMenus.add(dinerMenu);
MenuComponent dessertMenu = new Menu("Dessert Menu", "Desserts");
dinerMenu.add(dessertMenu);
MenuComponent applePie = new MenuItem("Apple Pie", "Homemade apple pie with a flaky crust", 1.59);
dessertMenu.add(applePie);
allMenus.print();
위의 코드에서는 각각의 Menu와 MenuItem 객체를 생성하고, 이를 조합하여 하나의 트리 구조를 만들어 출력하고 있습니다. 결과는 다음과 같이 출력됩니다.
All Menus (All menus combined)
------------------------
Pancake House Menu (Breakfast)
------------------------
Diner Menu (Lunch)
------------------------
Dessert Menu (Desserts)
------------------------
Apple Pie (Homemade apple pie with a flaky crust): 1.59
이를 통해 Java에서 컴포지트 패턴을 구현하는 방법과 실제 예제를 살펴보았습니다.
컴포지트 패턴은 객체 지향 디자인 패턴 중 하나로, 객체들을 트리 구조로 구성하여 부분-전체 계층을 나타내는 패턴입니다. 이번 글에서는 Java 언어에서 컴포지트 패턴을 구현하는 방법에 대해 알아보았습니다. Java에서는 인터페이스를 활용하여 컴포지트 패턴을 구현할 수 있으며, 실제 예제를 통해 이를 적용하는 방법도 살펴보았습니다. 이를 통해 객체들을 구성하여 다양한 작업을 수행할 수 있는 컴포지트 패턴의 활용법을 익히시기 바랍니다.