Java 디자인 패턴-12.Composite
            
          
        
Composite 패턴

“하나의 주문은 여러 상품으로 구성될 수 있다. 이 상품들은 여러 개의 다른 박스에 담길 수 있으며 이 박스들 역시 더 큰 박스에 담길 수 있다. 이런 구조는 뒤집힌 트리형태와 같다.”
(출처:https://refactoring.guru/design-patterns/composite)
해결하려는 문제
- 클라이언트는 트리tree구조의 자료구조에 접근할 때 부모 노드와 leaf노드를 접근하는 api가 틀리다면 소스가 복잡해진다. 부모와 노드를 일관된 방법으로 접근할 수 있다면 클라이언트 구현,변경,테스트,재사용이 쉬워진다.
 
특징/용도
- 트리tree구조의 자료구조에만 적용가능하다.
 
- Composite 객체는 요청을 자식객체들에게 순차적으로 전달forward한다.
 
클래스 다이어그램

소스
- Component : 공통 인터페이스로 leaf와 composition이 구현해야 할 메소드가 선언되어 있음
- Menu.java
1
2
3
4
5
  | 
package net.dskim.desingpattern.composite;
public interface Menu {
	public int getPrice();
}
  | 
 
 
- AggregateMenu.java
1
2
3
4
5
  | 
package net.dskim.desingpattern.composite;
public interface AggregateMenu extends Menu {
	public void addMenu(Menu menu);
}
  | 
 
 
 
- Leaf : 트리의 기본 요소로 하위 요소를 가지고 있지 않는다.
- Noodle.java
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
  | 
package net.dskim.desingpattern.composite;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class Noodle implements Menu {
	int price;
	
	public Noodle(int price) {
		this.price = price;
	}
	@Override
	public int getPrice() {
		log.info("price=={}", price);
		return price;
	}
}
  | 
 
 
- Rice.java
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
  | 
package net.dskim.desingpattern.composite;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class Rice implements Menu {
	int price;
	
	public Rice(int price) {
		this.price = price;
	}
	@Override
	public int getPrice() {
		log.info("price=={}", price);
		return price;
	}
}
  | 
 
 
 
- Composite : Component를 구현implement. leaf의 container역할
- SetMenu.java
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
  | 
package net.dskim.desingpattern.composite;
import java.util.ArrayList;
import java.util.List;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class SetMenu implements AggregateMenu {
	List<Menu> menus ;
	
	public SetMenu() {
		menus = new ArrayList<>();
	}
	@Override
	public void addMenu(Menu menu) {
		menus.add(menu);
	}
	@Override
	public int getPrice() {
		int price = 0;
		for(Menu menu : menus) {
			price += menu.getPrice();
		}
		log.info("price=={}", price);
		return price;
	}
}
  | 
 
 
 
참고