본문 바로가기
golang/design pattern

golang design pattern #8 Decorator

by PudgeKim 2021. 11. 13.

Decorator 패턴은 기존의 기능은 건드리지 않고 wrapping을 하는 것입니다.

go에서는 구조체 composition을 이용하여 이 패턴을 구현할 수 있습니다.

 

검색을 해보았을 때 피자 예제가 가장 좋은 것 같아서 이를 예시로 설명하겠습니다.

피자의 경우 제일 기본 피자를 시킨 후 여러가지 토핑을 추가할 수 있습니다.

이 때 토핑을 추가하는 것은 기존 피자는 건드리지 않고 정말 토핑만 추가하게 됩니다.
(토핑을 추가한다고 기존 피자의 재료를 바꾸거나 하지는 않는다는 뜻입니다.)

예제 코드에서는 토핑마다 가격이 다를 것이므로 각 토핑을 추가할때마다 토핑에 맞는 가격이 추가되는 예제를 구현해보겠습니다.

 

1
2
3
type pizza interface {
    getPrice() int
}
cs

우선 pizza interface를 구현해줍니다.

 

1
2
3
4
5
type combinationPizza struct {}
 
func (c *combinationPizza) getPrice() int {
    return 30
}
cs

위처럼 콤비네이션 피자를 주문했다고 가정해봅시다.

getPrice메서드를 구현함으로써 해당 구조체는 pizza 인터페이스 타입을 만족합니다.

 

1
2
3
4
5
6
7
8
type pineappleTopping struct {
    pizza pizza
}
 
func (p *pineappleTopping) getPrice() int {
    pizzaPrice := p.pizza.getPrice()
    return pizzaPrice + 10
}
cs

이제 콤비네이션 피자에 파인애플 토핑을 추가하기 위한 구조체입니다.

핵심은 이 구조체에서도 getPrice 메서드를 구현해서 pizza 인터페이스로 만드는 것입니다.

그래야 다른 토핑 구조체에서도 파인애플토핑을 추가한 피자에
토핑을 추가로 더할 수 있기 때문입니다.

 

1
2
3
4
5
6
7
8
type oliveTopping struct {
    pizza pizza
}
 
func (o *oliveTopping) getPrice() int {
    pizzaPrice := o.pizza.getPrice()
    return pizzaPrice + 5
}
cs

올리프 토핑 구조체입니다. 

이 구조체 역시 구조체 필드에 pizza 타입이 있고,
파인애플토핑 구조체도 getPrice 메서드를 구현함으로써 pizza 타입이므로 
파인애플토핑피자에 올리프토핑을 더할 수 있습니다.

 

1
2
3
4
5
6
combination := combinationPizza{}
 
addPineapple := pineappleTopping{&combination}
addOlive := oliveTopping{&addPineapple}
 
fmt.Println(addOlive.getPrice())
cs

위처럼 각 토핑을 더하면
콤비네이션피자 + 파인애플 토핑 + 올리브 토핑의 가격인 45가 나오게 됩니다.

'golang > design pattern' 카테고리의 다른 글

golang design pattern #10 Proxy  (0) 2021.11.15
golang design pattern #9 Flyweight  (0) 2021.11.14
golang design pattern #7 Composite  (0) 2021.11.12
golang design pattern #6 Bridge  (0) 2021.11.12
golang design pattern #5 Adapter  (0) 2021.11.12