카테고리 없음

[헤드퍼스트 디자인패턴] 9-2. 컴포지트 패턴(Composite Pattern)

혀내 2023. 4. 30. 16:44
반응형

컴포지트 패턴(Composite Pattern)

객체를 트리구조로 구성해 트리 전체의 복합적인 객체와 개별 객체를 똑같은 방법으로 다룰 수 있도록 도와주는 패턴입니다.
  • 메뉴, 서브메뉴, 서브서브메뉴로 구성된 트리구조 각각이 모두 복합 객체가 될 수 있습니다.
  • 간단한 코드로도 똑같은 작업을 전체 메뉴 구조에 반복적으로 적용할 수 있습니다.

 

 

구조

출처: https://refactoring.guru/ko/design-patterns/composite

1. Component 인터페이스: 트리에 들어가는 모든 요소들의 공통적인 인터페이스를 정의합니다.

2. Leaf 클래스: 트리의 기본 요소로, Composite에서 지원하는 기능을 구현합니다.

3. Composite 클래스:

  • 자식이 있는 구성 요소로, 행동을 정의하고 자식 구성 요소를 저장하는 역할을 맡습니다.
  • 요청을 받으면 작업을 자식 구성 요소에게 전달하고, 행동을 수행한 다음 최종 결과를 클라이언트에게 반환합니다.

4. Client 클래스: Component 인터페이스를 사용해 트리 내 모든 객체들을 조작할 수 있습니다.

 

 

 

컴포지트 패턴은 단일 책임 원칙을 깨는 대신 '투명성'을 확보하는 패턴입니다.

투명성이란 한 인터페이스에 자식을 관리하는 기능과 잎의 기능을 전부 넣어 클라이언트가 복합 객체와 잎을 똑같은 방식으로 처리할 수 있도록 만드는 것을 말합니다. 클라이언트의 입장에서는 어떤 원소가 복합 객체이거나, 잎인지 투명하게 확인할 수 있습니다.

 

 

예제

8-1. 반복자 패턴에서 사용했던 예제를 다시 살펴보겠습니다. PancakeMenu는 그대로 두되 DinerMenu에만 디저트 서브 메뉴를 추가하려고 합니다. 반복자 패턴을 적용한 기존 아키텍처로는 구현에 한계가 있을 것 같은데.. 컴포지트 패턴을 적용해 해결해볼까요?

 

 

MenuComponent 인터페이스 생성

public abstract class MenuComponent {
    
    public void add(MenuComponent menuComponent) {
        throw new UnsupportedOperationException();
    }
    
    public void remove(MenuComponent menuComponent) {
        throw new UnsupportedOperationException();
    }
    
    public MenuComponent getChild(int i) {
        throw new UnsupportedOperationException();
    }
    
    
    public String getName() {
        throw new UnsupportedOperationException();
    }
    
    public String getDescription() {
        throw new UnsupportedOperationException();
    }
    
    public double getPrice() {
        throw new UnsupportedOperationException();
    }
    
    public boolean isVegeterian() {
        throw new UnsupportedOperationException();
    }
    
    
    public void print() {
        throw new UnsupportedOperationException();
    }
}

 

 

메뉴판에 들어갈 메뉴 항목인 MenuItem 클래스 생성하기

public class MenuItem extends MenuComponent {
    String name;
    String description;
    boolean vegeterian;
    double price;
    
    public MenuItem(String name, String description, boolean vegetarian, double price) {
        this.name = name;
        this.description = description;
        this.vegetarian = vegetarian;
        this.price = price;
    }
    
    public String getName() {
        return name;
    }
    
    public String getDescription() {
        return description;
    }
    
    public double getPrice() {
        return price;
    }
    
    public boolean isVegeterian() {
        return vegetarian;
    }
    
    
    public void print() {
        ...
    }

 

 

복합 객체 클래스인 Menu 클래스 생성하기

public class Menu extends MenuComponent {
    List<MenuComponent> menuComponents = new ArrayList<MenuComponent>();
    String name;
    String description;
    
    public Menu(String name, String description) {
        this.name = name;
        this.description = description;
    }

    public void add(MenuComponent menuComponent) {
        menuComponents.add(menuComponent);
    }
    
    public void remove(MenuComponent menuComponent) {
        menuComponents.remove(menuComponent);
    }
    
    public MenuComponent getChild(int i) {
        return menuComponents.get(i);
    }
    
    public String getName() {
        return name;
    }
    
    public String getDescription() {
        return description;
    }
    
    public void print() {
        System.out.println("\n" + getName());
        System.out.println(", " + getDescription());
        System.out.println("-----------------------------------");
        
        for (MenuComponent menuComponent : menuComponents) {
            menuComponent.print();
        }
    }
}

 

 

종업원이 새로 만든 메뉴 구조를 사용하도록 수정하기

public class Waitress {
    MenuComponent allMenus;
    
    public Waitress(MenuComponent allMenus) {
        this.allMenus = allMenus;
    }
    
    public void printMenu() {
        allMenus.print();
    }
}

 

 

 

 

 

 

헤드 퍼스트 디자인 패턴 - YES24

유지관리가 편리한 객체지향 소프트웨어 만들기!“『헤드 퍼스트 디자인 패턴(개정판)』 한 권이면 충분하다.이유 1. 흥미로운 이야기와 재치 넘치는 구성이 담긴 〈헤드 퍼스트〉 시리즈! 하나

www.yes24.com

 

반응형