기타
컴포지트 패턴(Composite Pattern) 간단히 살펴보기
D.Y
2023. 4. 30. 14:57
반응형
Composite Pattern
컴포짓 패턴
그룹 전체와 개별 객체를 동일하게 처리할 수 있는 패턴
- 클라이언트 입장에서 ‘전체’나 ‘부분’이나 모두 동일한 컴포넌트로 인식할 수 있는 계층을 만든다. (Part-Whole Hierarchy)
예를들어, 가방에 물건(아이템)이 5가지 존재한다고 생각해보자.
- 물
- 립밤
- 향수
- 노트북
- 안경
물건들은 각각 쓰임새는 다르지만, 그에 해당하는 이름과 가격이 정해져있다.
이때 우리는 물건의 각각의 가격과 가방안에 든 모든 물건들의 가격을 알고 싶다고 할 경우에 컴포짓 패턴을 유용하게 사용할 수 있다.
가방 → 컴포지트를 나타내고 컴포지트는 안에 컴포넌트들을 갖고 있다.
컴포넌트 → 물, 향수 등이 해당되고 컴포지트에 기능 실행을 요청하면 컴포지트는 포함하고 있는 컴포넌트들의 기능 실행을 통해 값을 계산한다.
아래 예제코드는 Go를 사용하여 작성하였다. (전체 코드는 여기에 있다.)
main 코드 작성
func main() {
var (
water src.Item
perfume src.Item
glasses src.Item
laptop src.Item
)
water = src.NewWater("삼다수", 2000)
perfume = src.NewPerfume("재즈클럽", 140000)
glasses = src.NewGlasses("젠틀몬스터", 249000)
laptop = src.NewLaptop("맥북 프로", 3990000)
// 가방에 물건 담기
bag := src.NewBag("샘소나이트", 129000)
bag.AddItem(water)
bag.AddItem(perfume)
bag.AddItem(glasses)
bag.AddItem(laptop)
// 아이템 가격 출력하기
fmt.Println(water.Name() + ": " + fmt.Sprint(water.Price()))
fmt.Println(perfume.Name() + ": " + fmt.Sprint(perfume.Price()))
fmt.Println(glasses.Name() + ": " + fmt.Sprint(glasses.Price()))
fmt.Println(laptop.Name() + ": " + fmt.Sprint(laptop.Price()))
fmt.Println(bag.Name() + ": " + fmt.Sprint(bag.Price()))
// 가방에 들은 모든 물건의 가격 출력하기
fmt.Println("총 가격: " + fmt.Sprint(bag.ItemTotalPrice()))
}
컴포넌트 인터페이스로 Item 인터페이스 정의
type Item interface {
Name() string
Price() int
}
물, 향수, 노트북 객체 생성
// 물
type Water struct {
name string
price int
}
func NewWater(name string, price int) *Water {
return &Water{
name: name,
price: price,
}
}
func (p Water) Name() string {
return p.name
}
func (p Water) Price() int {
return p.price
}
// 향수
type Perfume struct {
name string
price int
}
func NewPerfume(name string, price int) *Perfume {
return &Perfume{
name: name,
price: price,
}
}
func (p Perfume) Name() string {
return p.name
}
func (p Perfume) Price() int {
return p.price
}
// 노트북
type Laptop struct {
name string
price int
}
func NewLaptop(name string, price int) *Laptop {
return &Laptop{
name: name,
price: price,
}
}
func (l Laptop) Name() string {
return l.name
}
func (l Laptop) Price() int {
return l.price
}
마지막으로 컴포지트에 해당하는 가방 생성
package src
type Bag struct {
name string
price int
items []Item
}
func NewBag(name string, price int) *Bag {
return &Bag{
name: name,
price: price,
items: nil,
}
}
func (b Bag) Name() string {
return b.name
}
func (b Bag) Price() int {
return b.price
}
func (b *Bag) AddItem(item Item) {
b.items = append(b.items, item)
}
func (b Bag) ItemTotalPrice() int {
var itemTotalPrice int
// 컴포넌트 실행
for _, v := range b.items {
itemTotalPrice += v.Price()
}
return itemTotalPrice
}
모두 즐거운 코딩하세요~
참조
- [도서] 개발자가 반드시 정복해야할 객체지향과 디자인 패턴
- [인프런] 코딩으로 학습하는 GoF의 디자인패턴
반응형