구조 패턴 - Composite

이유석·2022년 6월 27일
0

Design Pattern

목록 보기
7/10
post-thumbnail

Composite 패턴

정의

  • 복합 객체 그룹(전체)과 단일 객체를 동일하게 취급하거나 다룰 수 있게 해주는 방식으로, 재귀적 특성을 띄며 트리(tree) 구조에 가까운 패턴이다.

구조

복합체 패턴의 구조는 크게 3가지로 분류된다.

1. Base Component

  • 클라이언트가 Composition(복합체) 내의 오브젝트들을 다루기 위해 제공되는 인터페이스를 말합니다.

  • 베이스 컴포넌트는 인터페이스 또는 추상 클래스로 정의되며 모든 오브젝트들에게 공통되는 메소드를 정의해야 합니다.

2. Leaf

  • Composition 내의 오브젝트들의 행동을 정의합니다.

  • 단일 객체를 표현할 클래스로, 그룹의 구성원 역할을 하며 트리구조로 따지면 가장 밑단에 존재하는 나뭇잎 역할을 한다고 보면 됩니다.

  • Base Component를 구현합니다. 그리고 다른 컴포넌트에 대해 참조를 가지면 안됩니다.

3. Composite

  • Composition(복합체)를 표현할 클래스로, 자식으로 여러개의 Component 타입 멤버를 수용할 수 있도록 구현되어 있어야 합니다.

  • Leaf 객체들로 이루어져 있으며 Base Component 내 명령들을 구현합니다.

예제 코드

파워포인트에 삼각형, 원을 각각 하나씩 만들어 놓고 삼각형과 원을 그룹화 했다고 가정하겠습니다. 이제 우리는 모든 도형을 빨강색으로 색을 칠하려고 합니다.

이때 우리가 채우기 버튼을 누를 때 선택하는 것이 어떤 도형인지, 혹은 그룹인지에 대해서 구분하지 않아도 됩니다. 파워포인트에서는 도형 하나에 대한 채우기와 그룹 전체에 대한 채우기 버튼이 같습니다.

1. Base Component
Base Component는 Leaf와 Composite의 공통되는 메소드들을 정의해야 합니다.
예제에서는 Shape 인터페이스 내에 각각 도형마다 색을 입히는 draw() 메소드를 정의하도록 하겠습니다.

Shape.java

public interface Shape {

	public void draw(String fillColor);

}

2. Leaf Objects
Leaf 객체들은 복합체에 포함되는 요소로, Base Component를 구현해야 합니다.
예제에서는 Triangle과 Circle 클래스를 정의하도록 하겠습니다.

Triangle.java

public class Triangle implements Shape {

	@Override
    public void draw(String fillColor) {
    	System.out.println("Drawing Triangle with color " + fillColor);
    }
    
}

Circle.java

public class Circle implements Shape {

	@Override
    public void draw(String fillColor) {
    	System.out.println("Drawing Circle with color " + fillColor);
    }

}

3. Composite Objects
Composite 객체는 Leaf 객체들을 포함하고 있으며, Base Component를 구현할 뿐만 아니라 Leaf 그룹에 대해 add와 remove를 할 수 있는 메소드들을 클라이언트에게 제공합니다.

Drawing.java

public class Drawing implements Shape {

	// Leaf 객체들을 저장할 수 있는 구조체
    private List<Shape> shapeList = new ArrayList<Shape>();
    
    @Override
    public void draw(String fillColor) {
    	for(Shape s : shapeList) {
        	s.draw(fillColor);
        }
    }
    
    // adding shape to drawing
    public void add(Shape s) {
    	shapeList.add(s);
    }
    
    // removing shape from drawing
    public void remove(Shape s) {
    	shapeList.remove(s);
    }
	
    // removing all shapes
    public void clear() {
        System.out.println("Clearing all the shapes from drawing");
        this.shapes.clear();
    }
    
}

여기서 중요한 것은 Composite Object 또한 Base Component를 구현해야 한다는 것입니다.
그렇게 해야만 클라이언트가 Composite 객체에 대해서 다른 Leaf들과 동일하게 취급될 수 있습니다.

이제 위에서 작성한 예제 코드를 테스트 할 수 있는 코드를 작성해 보겠습니다.

TestCompositePattern.java

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");
        }
    }
}

출력 결과

Drawing Triangle with color Red
Drawing Triangle with color Red
Drawing Circle with color Red
Drawing Triangle with color Green
Drawing Triangle with color Green
Drawing Circle with color Green
Drawing Triangle with color Green
Drawing Circle with color Green
profile
https://github.com/yuseogi0218

0개의 댓글