구조패턴 중 하나인 컴포지트 패턴을 알아봅시다.
바로 예시부터 살펴보겠습니다.
예시
파일 시스템을 예로 들겠습니다.
파일 시스템에는 파일과 폴더가 있고 폴더안에는 또 파일과 폴더를 생성할 수 있습니다.
파일 시스템은 파일과 폴더 모두 크기를 알 수 있고 이름을 알 수 있습니다.
공통된 기능을 인터페이스로 만듭니다.
public interface FileSystem {
int getSize();
String getName();
}
파일과 폴더를 위 FileSystem 인터페이스를 구현해봅시다.
package Structural.composite;
public class File implements FileSystem{
private int size;
private String name;
public File(int size, String name) {
this.size = size;
this.name = name;
}
@Override
public int getSize() {
return size;
}
@Override
public String getName() {
return name;
}
}
package Structural.composite;
import java.util.ArrayList;
import java.util.List;
public class Folder implements FileSystem {
private String name;
private List<FileSystem> files = new ArrayList<>();
public Folder(String name) {
this.name = name;
}
public void add(FileSystem fileSystem) {
files.add(fileSystem);
}
@Override
public int getSize() {
int total = 0;
for (FileSystem file : files) {
total += file.getSize();
}
System.out.println(name + "의 폴더 크기는 " + total + "입니다.");
return total;
}
@Override
public String getName() {
System.out.print(name + "의 폴더 안에 ");
for (FileSystem file : files) {
System.out.print(file.getName());
}
System.out.print("이 있습니다.\n");
return name;
}
}
이 폴더 클래스가 컴포지트 패턴의 핵심 클래스입니다.
폴더안에 하위 파일, 폴더을 가지고 있습니다. (List<FileSystem>)
요청을 전달받으면 폴더는 작업을 하위 요소들에 위임하고 중간 결과들을 처리한 다음 최종 결과들을 클라이언트에 반환합니다.
이렇게 구현하게되면 폴더 하위에 폴더를 계속해서 생성할 수 있습니다.
public static void main(String[] args) {
Folder 큰상자 = new Folder("큰상자");
Folder 작은상자1 = new Folder("작은상자1");
Folder 작은상자2 = new Folder("작은상자2");
큰상자.add(작은상자1);
큰상자.add(작은상자2);
File 사과 = new File(256, "사과");
작은상자1.add(사과);
File 귤 = new File(256, "귤");
File 딸기 = new File(256, "딸기");
작은상자2.add(귤);
작은상자2.add(딸기);
큰상자.getSize();
큰상자.getName();
}
결과
작은상자1의 폴더 크기는 256입니다.
작은상자2의 폴더 크기는 512입니다.
큰상자의 폴더 크기는 768입니다.
큰상자의 폴더 안에 작은상자1의 폴더 안에 사과이 있습니다.
작은상자1작은상자2의 폴더 안에 귤딸기이 있습니다.
작은상자2이 있습니다.
컴포지트 패턴 구조

1. Component
위 예시에서는 FileSystem 인터페이스입니다. 파일과 폴더 등 요소들의 기능들을 정의합니다.
2. Leaf
위 예시에서는 File 클래스입니다. 하위요소가 없는 기본 요소입니다.
3. Composite
위 예시에서 Folder 클래스입니다. 하위 요소들이 있는 요소입니다.
기능 요청을 받으면 하위 요소들에게 기능을 위임하고 최종 결과를 클라이언트에게 반환합니다.
4.Client
위 예시에서는 main 함수가 됩니다.
인터페이스를 통해 모든 요소들과 작동합니다. 트리의 모든 단순 요소 및 복합 요소들에게 같은 방식의 작업을 진행할 수 있습니다.
장단점
장점
- 다형성과 재귀를 사용해 복잡한 트리 구조를 더 편리하게 작업할 수 있습니다.
- OCP를 지키며새로운 요소 유형들을 도입할 수 있습니다. (FileSystem의 구현체라면 추가할 수 있습니다.)
단점
- 기능이 다른 클래스들에는 공통 인터페이스 제공하기 어렵고 과도하게 일반화해야하여 이해하기 어렵습니다.
'리팩토링 > 디자인패턴' 카테고리의 다른 글
| [디자인패턴] 상태패턴 (3) | 2023.01.01 |
|---|---|
| [디자인 패턴] 데코레이터 패턴 (3) | 2022.12.26 |
| [디자인 패턴] 템플릿 메서드 패턴 (1) | 2022.12.10 |
| [디자인패턴] 퍼사드 패턴 (1) | 2022.11.26 |
| [디자인패턴] 어댑터 패턴 (1) | 2022.11.14 |