Factory Pattern

1. factory method pattern

객체를 생성하기 위한 인터페이스를 정의하는데, 어떤 클래스의 인스턴스를 만들지는 서브클래스에서 결정한다.

package main

import (
    "errors"
    "fmt"
)

type Character interface {
    Attack()
}

const (
    warrior = iota
    mage
)

type Warrior struct {
}

func (w *Warrior) Attack() {
    fmt.Println("sword attack")
}

type Mage struct {
}

func (m *Mage) Attack() {
    fmt.Println("magic attack")
}
  • Factory struct
type CharacterFactory struct {
}

func (f *CharacterFactory) Create(job int) (Character, error) {
    switch job {
    case warrior:
        return &Warrior{}, nil
    case mage:
        return &Mage{}, nil
    default:
        return nil, errors.New("unsupported character type")
    }
}

func main() {
    cf := &CharacterFactory{}

    c1, _ := cf.Create(warrior)
    c2, _ := cf.Create(mage)
    c1.Attack()
    c2.Attack()
}
  • Function
func NewCharacter(job int) (Character, error) {
    switch job {
    case warrior:
        return &Warrior{}, nil
    case mage:
        return &Mage{}, nil
    default:
        return nil, errors.New("unsupported character type")
    }
}

func main() {
    c1, _ := NewCharacter(warrior)
    c2, _ := NewCharacter(mage)
    c1.Attack()
    c2.Attack()
}

실행결과

sword attack
magic attack

2. factory generator

1) functional

type Clothes struct {
    kind, color string
    price int
}

func NewClothesFactory(kind string, price int) func(color string) *Clothes {
    return func(color string) *Clothes {
        return &Clothes{kind, color, price}
    }
}

func main() {
    jeanFactory := NewClothesFactory("jean", 25000)
    skirtFactory := NewClothesFactory("skirt", 18000)

    jean := jeanFactory("blue")
    skirt := skirtFactory("black")
    skirt2 := skirtFactory("white")

    fmt.Println(jean)
    fmt.Println(skirt)
    fmt.Println(skirt2)
}

2) struct

type Clothes struct {
    kind, color string
    price int
}

type ClothesFactory struct {
    kind string
    price int
}

func (f *ClothesFactory) Create(color string) *Clothes {
    return &Clothes{f.kind, color, f.price}
}

func NewClothesFactory(kind string, price int) *ClothesFactory {
    return &ClothesFactory{kind, price}
}

func main() {
    jeanFactory := NewClothesFactory("jean", 25000)
    skirtFactory := NewClothesFactory("skirt", 18000)

    jean := jeanFactory.Create("blue")
    skirt := skirtFactory.Create("black")
    skirt2 := skirtFactory.Create("white")

    fmt.Println(jean)
    fmt.Println(skirt)
    fmt.Println(skirt2)
}

실행결과

&{jean blue 25000}
&{skirt black 18000}
&{skirt white 18000}