본문 바로가기
golang/design pattern

golang design pattern #3 Prototype

by PudgeKim 2021. 11. 11.

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