컴포짓 패턴
- 개별 객체와 객체 그룹을 동일하게 다루기 위한 디자인 패턴
- 클라이언트 입장에서는 `전체`나 `부분`이나 모두 동일한 컴포넌트로 인식할 수 있도록 계층 구조를 만듦 (Part-Whole Hierarchy)
- 단, 트리 구조를 사용하여 객체를 구성해야한다는 제약 조건 존재

주요 구성 요소
1. Component
- 공통 인터페이스를 정의
- Compsite 및 Leaf가 구현해야하는 메서드를 선언
2. Leaf
- 트리의 말단 요소로 실제 작업을 수행
- Leaf 노드는 자식 노드를 가질 수 없음
3. Composite
- 자식 노드를 가지는 복합 노드
- 자식 노드를 관리하며 Component의 메서드를 구현
컴포짓 패턴 구현 예시
1. Component 인터페이스 정의
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
interface Graphic { | |
void draw(); | |
} |
2. Leaf 클래스 정의
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Circle implements Graphic { | |
@Override | |
public void draw() { | |
System.out.println("Drawing a Circle"); | |
} | |
} | |
class Square implements Graphic { | |
@Override | |
public void draw() { | |
System.out.println("Drawing a Square"); | |
} | |
} |
3. Composite 클래스 정의
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class CompositeGraphic implements Graphic { | |
private List<Graphic> childGraphics = new ArrayList<>(); | |
public void add(Graphic graphic) { | |
childGraphics.add(graphic); | |
} | |
public void remove(Graphic graphic) { | |
childGraphics.remove(graphic); | |
} | |
@Override | |
public void draw() { | |
for (Graphic graphic : childGraphics) { | |
graphic.draw(); | |
} | |
} | |
} |
4. Client 코드 예시
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class Client { | |
public static void main(String[] args) { | |
// 개별 객체 생성 | |
Circle circle = new Circle(); | |
Square square = new Square(); | |
Circle circle2 = new Circle(); | |
// Composite 객체 생성 | |
CompositeGraphic compositeGraphic = new CompositeGraphic(); | |
CompositeGraphic anotherCompositeGraphic = new CompositeGraphic(); | |
// 트리 구조 구성 | |
compositeGraphic.add(circle); | |
compositeGraphic.add(square); | |
anotherCompositeGraphic.add(circle2); | |
compositeGraphic.add(anotherCompositeGraphic); | |
// 전체 트리 구조 그리기 | |
compositeGraphic.draw(); | |
} | |
} |
부연 설명
- Graphic 인터페이스: draw 메서드를 정의하여 모든 그래픽 요소들이 이를 구현하도록 메서드 선언
- Circle과 Square 클래스 (Leaf): Graphic 인터페이스를 구현하며 draw 메서드를 통해 구체적인 작업을 수행
- CompositeGraphic 클래스 (Composite): Graphic 인터페이스를 구현하며, 자식 그래픽 요소들을 추가, 제거 및 그리기 작업을 수행
- Client: 클라이언트 코드로, 트리 구조를 구성하고 전체 트리 구조를 그림
컴포짓 패턴 장단점
장점
- 복잡한 트리 구조를 편리하게 사용할 수 있음
- Composite 클래스를 통해 다형성과 재귀를 활용할 수 있음
- 클라이언트 코드를 변경하지 않으면서 새로운 엘리먼트 타입(Leaf)을 추가 가능
단점
- 공통된 인터페이스를 가지는 트리를 만들어야 한다는 제약 사항 때문에 지나치게 일반화해야 하는 경우가 생길 수 있음
- Composite Pattern에서는 개별 객체(Leaf)와 복합 객체(Composite)가 동일한 인터페이스를 구현해야 함
- 이로 인해, 단순한 객체와 복합 객체 간의 공통된 인터페이스를 정의해야 하는데, 이는 때로 지나치게 일반화된 인터페이스를 만들어야 하는 상황을 초래할 수 있음
- ex) Leaf 클래스들이 개별적으로 특화된 메서드를 가져야 할 경우 공통 인터페이스로 추가하기 어려움
실무에서 쓰이는 컴포짓 패턴
1. 자바의 Swing 라이브러리
- Swing 라이브러리는 GUI 컴포넌트들을 구성하고 관리하는 데 있어 Composite Pattern을 활용하는 대표적인 예
- Swing은 자바에서 GUI 애플리케이션을 만들기 위한 라이브러리로, 다양한 컴포넌트들(버튼, 텍스트 필드, 패널 등)을 제공하며 이들을 계층적으로 배치 가능
- Swing의 모든 컴포넌트는 javax.swing.JComponent 클래스를 상속받으며 해당 클래스는 모든 컴포넌트가 가져야 할 공통된 메서드와 속성을 정의
- Swing의 주요 컴포넌트들은 다음과 같은 방식으로 Composite Pattern을 구현
- Component: 모든 Swing 컴포넌트의 기본 클래스이며 해당 클래스는 개별 컴포넌트와 복합 컴포넌트가 공통으로 구현해야 하는 메서드를 정의
- Leaf: JButton, JLabel, JTextField 등과 같은 실제 UI 요소들로, 개별적으로 동작
- Composite: JPanel, JFrame 등과 같이 다른 컴포넌트들을 포함할 수 있는 복합 요소
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class SwingExample { | |
/** | |
* JFrame, JTextField, JButton 다 타고타고 들어가면 Component에서 만나게 됨 | |
*/ | |
public static void main(String[] args) { | |
JFrame frame = new JFrame(); | |
JTextField textField = new JTextField(); | |
textField.setBounds(200, 200, 200, 40); | |
frame.add(textField); | |
JButton button = new JButton("click"); | |
button.setBounds(200, 100, 60, 40); | |
button.addActionListener(e -> textField.setText("Hello Swing")); | |
frame.add(button); | |
frame.setSize(600, 400); | |
frame.setLayout(null); | |
frame.setVisible(true); | |
} | |
} |
참고
코딩으로 학습하는 GoF의 디자인 패턴 - 백기선 강사님
반응형
'Design Pattern' 카테고리의 다른 글
[디자인 패턴] 퍼사드 패턴 (Facade Pattern) (0) | 2024.06.29 |
---|---|
[디자인 패턴] 데코레이터 패턴 (Decorator Pattern) (0) | 2024.06.29 |
[디자인 패턴] 브릿지 패턴 (Bridge Pattern) (0) | 2024.06.22 |
[디자인 패턴] 어댑터 패턴 (Adapter Pattern) (0) | 2024.06.22 |
[디자인 패턴] 프로토타입 패턴 (Prototype Pattern) (0) | 2024.06.22 |