Prototype 패턴은 매번 객체를 새로 생성하기보다는 original 객체를 복사해서 필요한 부분만 수정해서 사용하는 패턴입니다.
1
2
3
4
5
6
7
8
9
|
type Address struct {
City string
Postcode string
}
type Person struct {
Name string
Address *Address
}
|
cs |
위 같이 구조체가 정의되어 있다고 가정해봅시다.
1
2
3
4
5
6
7
|
alex := Person{
"alex",
&Address{"Seoul", "14321"},
}
sarah := alex
sarah.Address.City = "Busan"
|
cs |
위처럼 코드를 작성하게 되면 Address가 포인터 타입이기 때문에 alex의 주소도 Busan으로 바뀌어 버립니다.
이를 해결하기 위해서는 copy 메서드를 사용하는 등 여러 방법이 있겠지만 여기서는
gob 패키지를 이용하는 방법을 소개합니다.
1
2
3
4
5
6
7
8
9
10
11
|
func (p *Person) DeepCopy() *Person {
buf := bytes.Buffer{}
e := gob.NewEncoder(&buf)
_ = e.Encode(p)
decoder := gob.NewDecoder(&buf)
result := Person{}
_ = decoder.Decode(&result)
return &result
}
|
cs |
이렇게 gob 패키지를 이용해서 encoding과 decoding 과정을 거치게되면 포인터 형태로 이루어진
nested struct도 deepcopy가 가능합니다.
** 참고로 gob 패키지의 경우 struct의 field가 export되어있어야 copy를 합니다.
(즉, struct의 field 앞글자가 대문자여야 합니다.)
1
2
3
4
5
6
7
8
9
10
|
alex := Person{
"alex",
&Address{"Seoul", "14321"},
}
sarah := alex.DeepCopy()
sarah.Address.City = "Busan"
fmt.Println(alex.Address)
fmt.Println(sarah.Address)
|
cs |
위 코드를 실행해보시면 deepcopy가 되어서 alex의 주소는 여전히 Seoul로 되어있습니다.
'golang > design pattern' 카테고리의 다른 글
golang design pattern #6 Bridge (0) | 2021.11.12 |
---|---|
golang design pattern #5 Adapter (0) | 2021.11.12 |
golang design pattern #4 Singleton (0) | 2021.11.11 |
golang design pattern #2 Factory (0) | 2021.11.10 |
golang design pattern #1 Builder (0) | 2021.11.10 |