봄맞이 세일
팩토리 메서드

Go로 작성된 팩토리 메서드

팩토리 메서드는 제품 객체들의 구상 클래스들을 지정하지 않고 해당 제품 객체들을 생성할 수 있도록 하는 생성 디자인 패턴입니다.

팩토리 메서드는 메서드를 정의하며, 이 메서드는 직접 생성자 호출​(new 연산자)​을 사용하여 객체를 생성하는 대신 객체 생성에 사용되여야 합니다. 자식 클래스들은 이 메서드를 오버라이드하여 생성될 객체들의 클래스를 변경할 수 있습니다.

다양한 팩토리 패턴들과 개념들의 차이점을 이해하지 못하셨다면 팩토리 비교를 읽어보세요.

개념적인 예시

클래스 및 상속과 같은 객체 지향 프로그램 기능이 없으므로 Go에서 고전적인 팩토리 메서드 패턴을 구현하는 것은 불가능하나 여전히 Go에서 패턴의 기본 버전인 단순 팩토리​(Simple Factory)​를 구현할 수 있습니다.

이 예시에서는 팩토리 구조체​(struct)​를 사용하여 다양한 유형의 무기를 만들 것입니다.

먼저 총에 있어야 하는 모든 메서드들을 정의하는 i­Gun 인터페이스를 만듭니다. iGun 인터페이스를 구현하는 gun 구조체​(struct) 유형이 있습니다. 두 개의 구상 총들​(ak47musket)​은 총 구조체​(struct)​를 포함하고 모든 i­Gun 메서드들을 간접적으로 구현합니다.

gun­Factory 구조체​(struct)​는 팩토리의 역할을 하며, 수신된 인수를 기반으로 요청된 유형의 총들을 생성합니다. main.go는 클라이언트의 역할을 하며 ak47 또는 musket과 직접 상호작용하는 대신 gun­Factory에 의존하여 다양한 총들의 인스턴스를 생성하고, 생성을 문자열 매개변수만 사용하여 제어합니다.

iGun.go: 제품 인터페이스

package main

type IGun interface {
	setName(name string)
	setPower(power int)
	getName() string
	getPower() int
}

gun.go: 구상 제품

package main

type Gun struct {
	name  string
	power int
}

func (g *Gun) setName(name string) {
	g.name = name
}

func (g *Gun) getName() string {
	return g.name
}

func (g *Gun) setPower(power int) {
	g.power = power
}

func (g *Gun) getPower() int {
	return g.power
}

ak47.go: 구상 제품

package main

type Ak47 struct {
	Gun
}

func newAk47() IGun {
	return &Ak47{
		Gun: Gun{
			name:  "AK47 gun",
			power: 4,
		},
	}
}

musket.go: 구상 제품

package main

type musket struct {
	Gun
}

func newMusket() IGun {
	return &musket{
		Gun: Gun{
			name:  "Musket gun",
			power: 1,
		},
	}
}

gunFactory.go: 팩토리

package main

import "fmt"

func getGun(gunType string) (IGun, error) {
	if gunType == "ak47" {
		return newAk47(), nil
	}
	if gunType == "musket" {
		return newMusket(), nil
	}
	return nil, fmt.Errorf("Wrong gun type passed")
}

main.go: 클라이언트 코드

package main

import "fmt"

func main() {
	ak47, _ := getGun("ak47")
	musket, _ := getGun("musket")

	printDetails(ak47)
	printDetails(musket)
}

func printDetails(g IGun) {
	fmt.Printf("Gun: %s", g.getName())
	fmt.Println()
	fmt.Printf("Power: %d", g.getPower())
	fmt.Println()
}

output.txt: 실행 결과

Gun: AK47 gun
Power: 4
Gun: Musket gun
Power: 1

다른 언어로 작성된 팩토리 메서드

C#으로 작성된 팩토리 메서드 C++로 작성된 팩토리 메서드 자바로 작성된 팩토리 메서드 PHP로 작성된 팩토리 메서드 파이썬으로 작성된 팩토리 메서드 루비로 작성된 팩토리 메서드 러스트로 작성된 팩토리 메서드 스위프트로 작성된 팩토리 메서드 타입스크립트로 작성된 팩토리 메서드