추상 공장 패턴 🏭

Abstract Factory 패턴은 창조적인 디자인 패턴입니다. 유사한 제품의 여러 제품군을 만들어야 할 때 사용됩니다.

피자 체인의 예를 사용하여 이 패턴을 이해합시다.

피자 가게



당신이 도시 주변에 피자 가게를 여는 사업의 책임자라고 가정해 보십시오. 귀하의 많은 책임 중 하나는 도미노 또는 피자 헛과 같은 동일한 브랜드에 속하도록 지정된 상점의 모든 식품 품목(이 경우 피자 및 마늘 빵)을 유지 관리하는 것입니다.

여러 가지 방법이 있습니다. 생각나는 가장 간단한 것 중 하나는 피자 헛 또는 도미노 유형의 피자를 만드는 공장과 마늘 빵을 위한 또 다른 유사한 공장을 만드는 것입니다.

Note: If you're not sure about how normal factories work, you can take a look at this example



별도의 공장을 갖는 단점은 이제 지정된 상점에서 사용자가 원하는 올바른 유형의 피자, 마늘 빵을 선택하는 것을 신뢰한다는 것입니다. 그들이 피자 오두막 마늘 빵과 함께 도미노 피자를 제공하는 실수를 저지르면 고객은 화를 낼 것이고 당신은 또한 이러한 각 체인과의 가상 계약을 위반하게 될 것입니다.

괜찮아요. 더 간단한 방법이 있습니다

각 개별 제품(피자 및 마늘 빵)에 대한 공장을 만드는 대신 각 개별 브랜드에 대한 공장을 만들 수 있습니다. 이 두 팩토리에 creating a pizzacreating a garlic bread 에 대한 규정이 있어야 합니다.

그런 다음 매장을 차릴 때 매장 관리자에게 피자 헛 공장이나 도미노 공장 중 하나를 제공하고 실수로 제품을 섞거나 맞추는 일이 없도록 자신 있게 쉴 수 있습니다.

이것을 코드로 번역해보자:

팩토리 작성을 시작하기 전에 먼저 제품을 생성해 보겠습니다.


일반 피자


type iPizza interface {
    GetPrice() float64
    GetName() string
    GetToppings() []string
}

type pizza struct {
    name     string
    price    float64
    toppings []string
}

func (p *pizza) GetName() string {
    return p.name
}

func (p *pizza) GetPrice() float64 {
    return p.price
}

func (p *pizza) GetToppings() []string {
    return p.toppings
}



브랜드 피자


type pizzaHutPizza struct {
    pizza
}

type dominosPizza struct {
    pizza
}



일반 마늘 빵


type iGarlicBread interface {
    GetPrice() float64
    GetName() string
}

type garlicBread struct {
    name  string
    price float64
}

func (g *garlicBread) GetName() string {
    return g.name
}

func (g *garlicBread) GetPrice() float64 {
    return g.price
}



브랜드 마늘빵


type pizzaHutGarlicBread struct {
    garlicBread
}

type dominosGarlicBread struct {
    garlicBread
}

우리는 두 제품을 모두 만들었습니다. 둘 다 공통 인터페이스를 구현하므로 최종 사용자가 더 쉽게 사용할 수 있습니다. 말장난 😉

이제 각각에 대한 팩토리를 생성하는 방법을 살펴보겠습니다.


일반 공장


type iPizzaFactory interface {
    createPizza() iPizza
    createGarlicBread() iGarlicBread
}

이제 PizzaHutFactoryDominosFactory 모두 이 인터페이스를 구현하여 균일한 기능을 노출할 수 있습니다.


브랜드 공장


type PizzaHutFactory struct {}

func (p *PizzaHutFactory) createPizza(): iPizza {
    return &pizzaHutPizza{
        pizza{
            name:     "pepperoni",
            price:    230.3,
            toppings: []string{"olives", "mozzarella", "pork"},
        },
    }
}

func (p *pizzaHutFactory) createGarlicBread() iGarlicBread {
    return &pizzaHutGarlicBread{
        garlicBread{
            name:  "garlic bread",
            price: 180.99,
        },
    }
}



type dominosFactory struct{}

func (d *dominosFactory) createPizza() iPizza {
    return &dominosPizza{
        pizza{
            name:     "margherita",
            price:    200.5,
            toppings: []string{"tomatoes", "basil", "olive oil"},
        },
    }
}

func (d *dominosFactory) createGarlicBread() iGarlicBread {
    return &dominosGarlicBread{
        garlicBread{
            name:  "cheesy bread sticks",
            price: 150.00,
        },
    }
}

이제 공장 중 하나를 선택한 다음 계속해서 피자나 마늘 빵을 만들 수 있으며 공장의 모든 제품은 항상 동일한 제품군/브랜드 제품에 속하게 됩니다.

거의 다 왔어. 우리가 선택한 공장을 반환할 공장을 만들어 이 작업을 마무리하겠습니다. 혼란스럽다? 🤯 잠시 시간을 내어 그 문장을 다시 읽어보세요 😋

기본적으로 공장을 또 다른 객체로 생각하십시오. 이제 설정하려는 유형 또는 피자 가게(피자 헛 또는 도미노)를 기반으로 해당 특정 공장(다른 개체)에 대해 요청할 수 있습니다. 이러한 "객체"를 자동으로 가져오기 위해 이들 중 하나를 반환하는 다른 팩토리를 만들 수 있습니다.

도움이 되는 몇 가지 코드:


공장의 공장


func getPizzaFactory(chain string) (iPizzaFactory, error) {
    if chain == "P" {
        return &pizzaHutFactory{}, nil
    }
    if chain == "D" {
        return &dominosFactory{}, nil
    }
    return nil, fmt.Errorf("Enter a valid chain type next time")
}

이게 더 의미가 있을지도 몰라요 💡😁

기억해야 할 주요 사항은 다음과 같습니다. 추상 팩토리 패턴은 팩토리 팩토리를 구현합니다. 이 내부 공장은 특정 종류에 속하는 제품을 만드는 데 사용할 수 있습니다.

이 튜토리얼의 모든 코드는 this github repo에서 찾을 수 있습니다.

건배 ☕️

좋은 웹페이지 즐겨찾기