Project

Composite 디자인 패턴 적용하기

우주코딩 2021. 8. 3. 16:15

프로젝트 - composite 디자인 패턴

컴포지트 패턴 : 객체들의 관계를 트리구조로 구성하여 부분-전체 계층을 표현하는 패턴이다.

08- a 사용자가 직접 명령어를 입력하는 대신에 메뉴를 통해 명령을 실행하도록 변경
composite 패턴 적용 전
composite 디자인 패턴의 용도와 실행 원리를 이해한다.

08- b composite 패턴 적용 후
tree 구조를 갖는 객체를 다룰 때 유용한 설계구도

  1. 'component' 역할을 정의한다.
  • 직접 사용할 클래스가 아니기 때문에, 추상클래스로 정의
  • execute(): 서브 클래스에서 재정의해야하기 때문에, 추상 메서드로 선언
  1. 'composite' 역할을 정의한다.
  • MenuGroup 클래스 추가
    • execute() 구현: 메뉴를 출력하고 사용자로부터 번호를 입력받는 일을 한다.
    • 하위 메뉴를 다룰 수 있도록 add()/remove()/getChild() 메서드를 포함한다.

public class MenuGroup extends Menu {
  // 역할
  //- 다른 메뉴를 포함하는 컨테이너 역할을 수행한다.
  Menu[] childs = new Menu[100]; // Leaf 와 함께 다른 메뉴를 포함할 수 있다. 
  int size ;
  boolean disablePrevMenu;
  String prevMenuTitle = "이전 메뉴";

  // 생성자를 정의하지 않으면 컴파일러가 기본 생성자를 자동으로 추가해준다.
  // 문제는 컴파일러가 추가한 기본 생성자는 수퍼클래스의 기본 생성자를 호출하는데
  // Menu에 기본 생성자가 없기 때문에 컴파일 오류가 발생한다.
  // 따라서 개발자가 직접 생성자를 정의해야한다.

public void add(Menu child) {
    if(this.size == this.childs.length) {
      return; // 하위 메뉴를 저장할 배열이 꽉 찼다면 더이상 저장해서는 안된다.
    }

    this.childs[this.size++] = child;
  }

  // 배열에 들어있는 Menu 객체를 찾아 제거한다.
  public Menu remove(Menu child) {
    int index = indexOf(child);
    if(index == -1) {
      return null;
    }
    for(int i = index+1 ; i <this.size ; i++) {
      this.childs[i-1] = this.childs[i];
    }
    childs[--this.size] = null;
    return child;
  }


  // 배열에 들어있는 Menu객체의 인덱스를 알아낸다.
  public int indexOf (Menu child) {
    for(int i = 0; i < this.size ; i++) {
      if(childs[i] == child) {
        return i;
      }
    }
    return -1;
  }


  // 배열에 들어있는 Menu 객체를 찾는다
  public Menu getMenu(String title) {
    for(int i = 0; i < this.size ; i++) {
      if(this.childs[i].title.equals(title)) {
        return this.childs[i];        
      }
    }
    return null;
  }

execute(); 메서드는 메뉴 구성에 따라 코드를 작성한다.