팩토리 패턴 🏭

팩토리 패턴은 일반적으로 사용되는 창작 디자인 패턴입니다. 일반적으로 사용자가 여러 옵션 중에서 선택해야 할 때 사용됩니다.

이해를 돕기 위해 예를 들어 보겠습니다.

애완 동물 가게



이것이 애완 동물 가게에서 어떻게 작동하는지 시나리오를 생각해 봅시다. 이를 완전히 이해하기 위해 상점 소유자(developer가 공장을 생성함)와 고객(user이 인터페이스를 사용)의 관점에서 구현을 살펴보겠습니다.

소유자의 관점



당신이 개 가게의 주인이라고 가정해 보십시오. 당신이 소프트웨어 세계에 있기 때문에 모든 개는 당신이 가지고 있는 Dog 클래스의 인스턴스입니다. 이제 고객이 도착하면 Dog의 새 인스턴스를 만들고 채택하게 하면 됩니다.🐶

하지만 최근 들어 고객들이 다양화를 요구하기 시작했다. 고양이도 입양할 방법을 찾고 있습니다.😼

영리한 가게 주인으로서 당신은 이러한 수요가 계속해서 다양해질 수 있다는 것을 알게 되었습니다. 앞으로도 더욱 다양한 모습 기대하겠습니다.😨😤

고객을 위한 새로운 애완 동물을 생성하려면 강력하고 확장 가능한 시스템이 필요합니다.
엔터, 팩토리 패턴

애완 동물의 모든 공통 특성( features ) 목록을 작성합니다. 그들은 당신이 이름을 얻고, 그들이 만드는 소리를 얻고, 나이를 알 수 있습니다. 이 목록을 사용하면 다음 기능이 있는 인터페이스를 만들 수 있습니다.

type Pet interface {
    GetName() string
    GetAge() int
    GetSound() string
}

이제 동일한 기능을 가진 애완동물을 원하는 만큼 만들 수 있습니다( implement the same interface ). Pet 인터페이스를 구현하기만 하면 고양이, 개, 물고기, 앵무새 등 무엇이든 가질 수 있습니다!😯 지금부터 개와 고양이를 만들어 보겠습니다.

// pet is a struct that implements Pet interface and
// would be used in any animal struct that we create.
// See `Dog` and `Cat` below
type pet struct {
    name  string
    age   int
    sound string
}

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

func (p *pet) GetSound() string {
    return p.sound
}

func (p *pet) GetAge() int {
    return p.age
}

type Dog struct {
    pet
}

type Cat struct {
    pet
}

추가로 필요한 것은 사용자의 요청에 따라 다른 애완동물(개/고양이)을 반환하는 공장입니다. 간단히 말해서 사용자가 강아지를 달라고 하면 귀여운 강아지를 주세요.🙄🦮

func GetPet(petType string) Pet {
    if petType == "dog" {
        return &Dog{
            pet{
                name:  "Chester",
                age:   2,
                sound: "bark",
            },
        }
    }
    if petType === "cat" {
        return &Cat{
            pet{
                name:  "Mr. Buttons",
                age:   3,
                sound: "meow",
            },
        }
    }
}
GetPet 함수가 Pet - Not a Dog 또는 a Cat를 명시적으로 반환한다는 것만 알려주는 방법에 주목하세요. 따라서 이 함수는 확장에 열려 있습니다(Pet 인터페이스를 구현하는 더 많은 구조체를 작성하여). 더 많은 Pet 유형을 추가해도 어쨌든 Dog 를 원하는 기존 사용자에게는 영향을 미치지 않습니다.

축하합니다! 팩토리 패턴으로 펫샵을 만들었습니다🎉❤️

고객의 관점



사용자의 입장에서 살펴보겠습니다. 그들이해야 할 일은 원하는 구성 (이 경우 GetPet )으로 type 함수를 호출하는 것입니다. 그 대가로 그들이 아는 것은 Pet를 얻는다는 것뿐입니다.🤔 이것은 현실 세계의 사물 감각에서 이상하게 들릴 수 있지만 코드에 관해서는 추상화를 유지하는 것이 좋습니다.😌

사용자는 Pet 원하는 대로 자유롭게 "사용"할 수 있습니다. 이 "사용법"은 그들이 되찾은 애완동물의 유형에 관계없이 동일하게 유지됩니다(모든 애완동물이 공통 인터페이스를 구현하기 때문입니다!!).

테스트해봅시다

func describePet(pet Pet) string {
    return fmt.Sprintf("%s is %d years old. It's sound is %s", pet.GetName(), pet.GetAge(), pet.GetSound())
}

func main() {
    petType := "dog"

    dog := GetPet(petType)
    petDescription := describePet(dog)

    fmt.Println(petDescription)
    fmt.Println("-------------")

    petType = "cat"
    cat := GetPet(petType)
    petDescription = describePet(cat)

    fmt.Println(petDescription)
}

출력은 다음과 같아야 합니다.

Chester is 2 years old. It's sound is bark
-------------
Mr. Buttons is 3 years old. It's sound is meow

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

팩토리 패턴을 더 쉽게 이해할 수 있기를 바랍니다 🚀

건배 ☕️

좋은 웹페이지 즐겨찾기