데코레이터 패턴 🎁
Decorator 패턴은 인터페이스를 변경하지 않고 주어진 객체의 기능을 향상시켜야 할 때 사용되는 구조적 디자인 패턴입니다.
이 패턴에서는 일반적으로 특정 인터페이스를 구현하는 기본/베어본 클래스가 있습니다. 이와 함께 사용자가 인터페이스를 변경하지 않고 기본 클래스의 메서드를 향상시킬 수 있는 여러 "래퍼"클래스가 있습니다.
이는 "Wrapper"클래스도 동일한 인터페이스를 구현함을 의미합니다.
이것을 더 잘 이해하기 위해 예를 들어보겠습니다. 사용자 정보를 스토리지 시스템에 저장해야 하는 사용 사례와 저장하기 전에 일부 데이터를 암호화해야 할 때 어떤 일이 발생하는지 논의할 것입니다. 🗃
스토리지 시스템
사용자 데이터를 저장하는 웹사이트 잠재고객용 스토리지 시스템이 있다고 가정합니다. 이 경우에는
email
입니다. 훌륭한 개발자는 이 모듈을 매우 일반적으로 설계했으며 현재 조직의 여러 팀에서 사용하고 있습니다. 😎모든 것이 훌륭하게 들립니까? 여기 문제가 있습니다. 새로운 요구 사항이 있습니다. 팀만 사용자 데이터를 저장하기 전에 암호화하면 됩니다. 🤯
분명히 기존 모듈을 수정할 수 없습니다. 너무 많은 팀이 사용 중이며 사용하면 🙃 당신을 죽일 것입니다. 또한 모든 것을 처음부터 다시 작성할 수 없습니다. 당신은 그것을 위한 충분한 시간이 없으며 또한 이것을 해결하는 가장 좋은 방법이 아닙니다.
동료가 데코레이터 패턴에 대해 말한 것을 기억하고 이를 실행에 옮기기로 결정했습니다 💡. 진행 방법은 다음과 같습니다.
StorageSystem
및 writeInfo
두 가지 메서드가 포함된 readInfo
인터페이스가 있습니다. StorageSystem
를 구현하여 이전에 생성한 구조체는 GenericStorageSystem
입니다. - 이것은 단지 정보를 메모리에 저장한다고 가정합니다. StorageSystem
. 예, 반복합니다. 처음부터 새 구조체를 만들 수는 없습니다. GenericStorageSystem
를 사용해야 합니다. EncryptedStorageSystem
. GenericStorageSystem
를 감싸고 데이터를 암호화/복호화한 후 writeInfo
의 readInfo
및 writeInfo
를 각각 호출하는 readInfo
및 GenericStorageSystem
를 구현합니다. 짜잔! 많은 시간을 절약하고 확장 가능한 솔루션을 갖게 되었습니다. 여기, 당신의 노력에 대한 쿠키가 있습니다 🍪
Go 코드에서 이것이 어떻게 보이는지 봅시다.
type StorageSystem interface {
writeInfo(info string)
readInfo() string
}
type GenericStorageSystem struct {
info string
}
func (g *GenericStorageSystem) writeInfo(info string) {
// write information to file system as is.
fmt.Println("Writing info to the file system: ", info)
g.info = info
}
func (g *GenericStorageSystem) readInfo() string {
// Return info from file system as is.
fmt.Println("Reading info from the file system: ", g.info)
return g.info
}
type EncryptedStorageSystem struct {
storageSystem StorageSystem
}
func (e *EncryptedStorageSystem) writeInfo(info string) {
fmt.Println("Encrypting the data")
encryptedInfo := encrypt(info)
e.storageSystem.writeInfo(encryptedInfo)
}
func (e *EncryptedStorageSystem) readInfo() string {
info := e.storageSystem.readInfo()
decryptedInfo := decrypt(info)
fmt.Println("Decrypting info from the file system: ", decryptedInfo)
return decryptedInfo
}
더미
encrypt
및 decrypt
함수도 만들어 보겠습니다. 이것들은 문자열을 다른 방향으로 회전시킵니다.func encrypt (info string) string {
return info[1:len(info)] + string(info[0])
}
func decrypt (info string) string {
return string(info[len(info) - 1]) + info[0:len(info)-1]
}
💃🏻💃🏻. 실제로 확인해 보겠습니다.
func main() {
info := "[email protected]"
genericStorage := GenericStorageSystem{}
genericStorage.writeInfo(info)
genericStorage.readInfo()
fmt.Println("------------")
encryptedStorage = EncryptedStorage{
storageSystem: genericStorage,
}
encryptedStorage.writeInfo(info)
encryptedStorage.readInfo()
}
출력에서 다음을 확인해야 합니다.
Writing info to the file system: [email protected]
Reading info from the file system: [email protected]
------------
Encrypting the data
Writing info to the file system: [email protected]
Reading info from the file system: [email protected]
Decrypting info from the file system: [email protected]
두 경우의 최종 결과가 어떻게 유사한지 확인하십시오. 문자열을 작성하고 요청했을 때 동일한 문자열을 반환했습니다. 그러나 두 번째 경우에는 데이터를 저장하는 동안 암호화하고 읽는 동안 암호를 해독했습니다. 가장 중요한 부분은 이 모든 것이 사용자로부터 추상화된다는 것입니다.
있습니다 - 데코레이터 패턴 🎉
이제 데코레이터 패턴을 잘 이해했으므로 이것이 왜 좋은지 논의해 보겠습니다.
EncryptedStorageSystem
가 StorageSystem
인터페이스를 구현하고 임의의 StorageSystem
를 둘러싸고 있음을 주목하십시오. 뿐만 아니라 GenericStorageSystem
. 이것은 여러 재귀 래퍼를 만들 수 있기 때문에 매우 강력합니다. 이제 암호화한 후 데이터를 압축할 수도 있습니다. 💪🏽😁 Note: The Decorator pattern is different from the Adapter pattern because the adapter pattern converts one struct into another. Hence, there is a change in API. The decorator pattern, on the other hand, simply wraps around the existing struct without changing the API.
이 튜토리얼의 모든 코드는 이것this github repo에서 찾을 수 있습니다.
건배 ☕️
Reference
이 문제에 관하여(데코레이터 패턴 🎁), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/shubhamzanwar/decorator-pattern-19kb텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)