[프로타입 패턴]

인스턴스는 새 객체를 만들기 위해 자신을 복제(clone)하게 된다.

원칙은 "런타임"에 또 다른 "객체"를 생성한다는 것이다. 다시 말해 이 시점에 가서 클로닝(cloning)을 하는 객체의 "실제 복사본"이 만들어지는 것이다.

 

실행 시간 - 위키백과, 우리 모두의 백과사전

위키백과, 우리 모두의 백과사전. -->

ko.wikipedia.org

 

기존 자바를 사용했던 사람들에게 는 매우 익숙한 패턴처럼 보일 것이다.

모든 자바의 클래스는 Object를 상속하고, 이는 Clone()의 메서드를 제공하게 된다. 즉 객체의 복사를 제공한다.

 

왜 필요할까? 

객체의 정확한 복사본을 만들고자 할 때 필요하다고 정의되어있다. 특히나 Go에서는 slice, pointer에서 예외 상황이 발생한다.

아래의 예제를 보자.

결과 값의 3,4번째 줄을 확인해 보자. 동일한 주소값을 가지고 있다. 분명 새로운 키보드를 만들기 위해서 작성했지만 아래와 같이 동일한 주소값을 가지고 있다.

고에서 슬라이스는 포인터의 래퍼이다. 즉 메모리 주소의 포인터 값을 랩핑 한 배열이다. 당연히 이를 복사하면 우리가 가져오는 값들은 저 포인터 값을 복사한 값들을 들고 오게 된다. 이는 반드시 주의해야 한다.

 

	leopold := &Keyboard{
		Layout: vamilo.Layout,
		Switch: []string{"Gateron Mx Red", "Gateron Mx Blue"},
		KeyCap: vamilo.KeyCap,
	}

위와 같은 새로운 슬라이스를 선언하고 값을 넣어줘야 한다. 

 

아래와 같은 방법을 이용해서 복사하는 방법도 하나의 방법 중 하나이다.

gob를 이용해 스트림화시켜 직렬화 역직렬화시키는 방법을 이용해서 복사를 하는 것도 하나의 방법이 될 수도 있다.

 

Interface의 clone을 선언해서 이용하는 방법을 사용해 보자.

 

이번에는 인터페이스의 클론을 활용해서 인터페이스 자신을 반환하게 설정하였다.
이렇게 설정되면 클라이언트는 복사하고자 하는 대상으로 타입어설션이 가능해지며 유연성 있고, 확장가능한 코드구성이 가능해진다.

func Run() {
	sixty := &Keyboard{"60%", []string{"Cherry MX Blue", "Cherry MX Brown", "Cherry MX Red"}, "DSA"}

	keyboardClone := sixty.Clone().(*Keyboard)

	fmt.Println(keyboardClone)
}

 

+ Recent posts