복합체 패턴

정선호·2023년 5월 23일
0

Design Patterns

목록 보기
14/24

관련 문서

복합체(컴포지트 패턴)

위키피디아 - 컴포지트 패턴
설명 및 스도코드

  • 객체들을 트리 구조들로 구성한 후, 이러한 구조들과 개별 객체들처럼 작업할 수 있도록 하는 구조 패턴
  • 사용자가 단일 객체와 복합 객체 모두 동일하게 다루도록 함

복합체 패턴의 구조

  • 컴포넌트(Component) 인터페이스
    • 트리의 단순 요소들과 복잡한 요소들 모두에 공통적인 작업 설명
  • 잎(Leaf)
    • 트리의 기본 요소로 하위 구조가 없음
    • 대부분의 실제 작업들을 수행함
  • 컨테이너(복합체, Composite)
    • 하위 요소들(잎 또는 기타 컨테이너)이 있는 요소
    • 자녀들의 구상 클래스들을 알지 못하며 컴포넌트 인터페이스를 통해서만 모든 하위 요소들과 함께 작동
    • 요청을 전달받으면 컨테이너는 작업을 하위 요소들에 위임하고 중간 결과들을 처리한 다음 최종 결과들을 클라이언트에 반환
  • 클라이언트
    • 컴포넌트 인터페이스를 통해 모든 요소들과 작동
    • 따라서 클라이언트는 트리의 단순 요소들 또는 복잡한 요소들 모두에 대해 같은 방식으로 작업 가능

복합체 패턴의 적용

  • 나무와 같은 객체 구조를 구현해야 할 때
  • 클라이언트 코드가 단순 요소들과 복합 요소들을 모두 균일하게 처리하도록 하고싶을 때

다른 패턴과의 관계

  • 복합체 패턴 트리를 생성할 때 빌더를 사용할 수 있다. 빌더의 생성 단계들은 재귀적으로 작동하도록 프로그래밍할 수 있기 때문
  • 책임 연쇄 패턴은 종종 복합체 패턴과 함께 사용된다. 그러면 잎 컴포넌트가 요청을 받으면 해당 요청을 모든 부모 컴포넌트들의 체인을 통해 객체 트리의 뿌리까지 전달할 수 있다
  • 반복자들을 사용해 복합체 패턴 트리들을 순회할 수 있다
  • 비지터 패턴을 사용해 복합체 패턴 트리 전체를 대상으로 작업을 수행할 수 있다
  • RAM을 절약하기 위해 복합체 패턴 트리의 공유된 잎 노드들을 플라이웨이트들로 구현할 수 있다
  • 복합체 패턴 및 데코레이터는 둘 다 구조 다이어그램이 유사하다. 둘 다 재귀적인 합성에 의존하여 하나 또는 불특정 다수의 객체들을 정리하기 때문
    • 데코레이터는 복합체 패턴과 비슷하지만 자식 컴포넌트가 하나만 있음
    • 데코레이터는 래핑된 객체에 추가 책임들을 추가하는 반면 복합체 패턴은 자신의 자식들의 결과를 요약하기만 함
    • 데코레이터를 사용하여 복합체 패턴 트리의 특정 객체의 행동을 확장할 수 있음
  • 프로토타입 패턴을 적용하여 복잡한 구조들을 처음부터 다시 건축하는 대신 복제할 수 있음

Java를 이용해 구현한 도형 그리기

  • 컴포넌트 인터페이스
public interface Shape {
	// 공통 메서드
    public void draw(String fillColor);
}
public class Triangle implements Shape {
    @Override
    public void draw(String fillColor) {
        System.out.println("Drawing Triangle with color "+fillColor);
    }
}

public class Circle implements Shape {
    @Override
    public void draw(String fillColor) {
        System.out.println("Drawing Circle with color "+fillColor);
    }
}
  • 컨테이너
public class Drawing implements Shape {
 
    //collection of Shapes
    private List<Shape> shapes = new ArrayList<Shape>();
	
    @Override
    public void draw(String fillColor) {
        for(Shape sh : shapes) {
            sh.draw(fillColor);
        }
    }
	
    //adding shape to drawing
    public void add(Shape s) {
        this.shapes.add(s);
    }
	
    //removing shape from drawing
    public void remove(Shape s) {
        shapes.remove(s);
    }
	
    //removing all the shapes
    public void clear() {
        System.out.println("Clearing all the shapes from drawing");
        this.shapes.clear();
    }
}
  • 클라이언트
public class TestCompositePattern {
 
    public static void main(String[] args) {
        Shape tri = new Triangle();
        Shape tri1 = new Triangle();
        Shape cir = new Circle();
		
        Drawing drawing = new Drawing();
        drawing.add(tri1);
        drawing.add(tri1);
        drawing.add(cir);
		
        drawing.draw("Red");
		
        List<Shape> shapes = new ArrayList<>();
        shapes.add(drawing);
        shapes.add(new Triangle());
        shapes.add(new Circle());
        
        for(Shape shape : shapes) {
            shape.draw("Green");
        }
    }
}
profile
학습한 내용을 빠르게 다시 찾기 위한 저장소

0개의 댓글