Go로 만드는 웹5 - Decorator 패턴

솔다·2023년 1월 31일
0

Decorator란?

프로그래밍의 한 패턴인데, Original한 기능이 있는것에 부가적으로 붙이는 것을 말한다.

좀더 자세히 설명해보자면, 어떤 데이터를 보낸다고 가정해보자. Data를 보낼때, 압축하고/다른사람이 못보게 암호화를 하고/추척가능하도록 log를 달고/ 등등의 다른 것들을 추가해서야 전송이 된다. 이렇게 추가되는 것들이 Decorator다.

Decorator는 왜 쓰는가?

왜냐면, 여러가지 기능이 추가될 수 있는데, 변할 수 있기 때문이다. Original 기능은 그대로 사용하고, Decorator만 변경하면 편하게 변경할 수 있다.

Decorator 디자인

코딩을 할 때는 어떤식으로 설계를 할 것인가? 머리 박으면서 하면 할 수는 있지만, 어렵다. Design Pattern을 미리 정해놓고 만들기 시작하면, 편하고 누가 만들어도 패턴화해서 만들 수 있다.

Component는 interface이고, operation이라는 함수가 있다. 근데 이 operation()를 구현하는 게 두가지가 있다. 이 두가지는 ConcreteComponent 와 Decorator라는 놈이 구현을 하고 있다. Decorator 는 component를 variable로 가지고 있다. 이 componenet variable로 가지고 있는 operation을 호출하고, Decorator operation을 호출하는 식으로 작동한다.

Decorator 를 포함시킨 예시코드 작성연습

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를 구현해볼 예정이다.

0개의 댓글