프로그래밍의 한 패턴인데, Original한 기능이 있는것에 부가적으로 붙이는 것을 말한다.
좀더 자세히 설명해보자면, 어떤 데이터를 보낸다고 가정해보자. Data를 보낼때, 압축하고/다른사람이 못보게 암호화를 하고/추척가능하도록 log를 달고/ 등등의 다른 것들을 추가해서야 전송이 된다. 이렇게 추가되는 것들이 Decorator다.
Decorator는 왜 쓰는가?
왜냐면, 여러가지 기능이 추가될 수 있는데, 변할 수 있기 때문이다. Original 기능은 그대로 사용하고, Decorator만 변경하면 편하게 변경할 수 있다.
코딩을 할 때는 어떤식으로 설계를 할 것인가? 머리 박으면서 하면 할 수는 있지만, 어렵다. Design Pattern을 미리 정해놓고 만들기 시작하면, 편하고 누가 만들어도 패턴화해서 만들 수 있다.
Component는 interface이고, operation이라는 함수가 있다. 근데 이 operation()를 구현하는 게 두가지가 있다. 이 두가지는 ConcreteComponent 와 Decorator라는 놈이 구현을 하고 있다. Decorator 는 component를 variable로 가지고 있다. 이 componenet variable로 가지고 있는 operation을 호출하고, Decorator operation을 호출하는 식으로 작동한다.
Decorator 개념을 포함시킨 코드를 작성했다.
아래에 코드를 보면
package main
type Component interface {
Operator(string)
}
var sentData string
type SendComponent struct{}
func (self *SendComponent) Operator(data string) {
// Send data
sentData = data
}
type ZipComponenet struct {
com Component
//Decorator이기 때문에 이 안에 다른 Componenet를 가지고 있다.
}
func (self *ZipComponenet) Operator(data string) {
zipData, err := lzw.Write([]byte(data))
if err != nil {
panic(err)
}
self.com.Operator(string(zipData))
}
type EncryptoComponent struct {
key string
com Component
}
func (self *EncryptoComponent) Operator(data string) {
encryptData, err := cipher.Encrypt([]byte(data), self.key)
if err != nil {
panic(err)
}
self.com.Operator(string(encryptData))
}
func main() {
sender := &EncryptoComponent{key: "abcde",
com: &ZipComponenet{
com: &SendComponent{}}}
sender.Operator("Hello World")
fmt.Println(sentData)
}
Decorator 패턴으로 작성된 위의 코드를 보면, main()
에서 sender
변수를 선언할때, 내부에 interface들을 넣어주는 것으로, 실행하고 있음을 알 수 있다.
각각의 구조체를 보면, 내부에 Operator라는 함수를 담고 있어서 Decorator로 쉽게 호출할 수 있다. 순서대로 타고타고 가면서 실해이 되어서 함수의 실행이 완료되며, Decorator를 수정하고 싶다면, main()
에서 코드를 아래와 같이 수정한다.
func main() {
sender := &ZipComponenet{
com: &SendComponent{}}
sender.Operator("Hello World")
fmt.Println(sentData)
}
그러면 코드에서 볼 수 있듯이, 암호화하는 부분은 실행되지 않고, 나머지 decorator만 실행이 될것이다. 이런 식으로 손쉽게 변경할 수 있다는 장점이 있다. 지금 현재 코드는 암호화하고 압축 후에 보내는 부분만 작성되어 있는데, 반대로 받는 과정도 이와 동일하다. 다음에는 Decorator Handler를 구현해볼 예정이다.