Menu
Coddy logo textTech

추상 팩토리 패턴

Coddy GO 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨. 107개 중 88번째.

Abstract Factory 패턴은 구체적인 타입을 지정하지 않고 관련된 객체의 family를 생성하여 Factory 패턴을 확장합니다. 단일 factory function 대신, 여러 구체적인 factory가 implement하는 factory interface를 Define하며, 각 factory는 일관된 관련 객체 집합을 생성합니다.

버튼과 체크박스를 생성해야 하는 UI 툴킷을 생각해 보세요. 운영 체제마다 서로 다른 구현이 필요하지만, 구성 요소는 일관되게 함께 작동해야 합니다:

type Button interface {
    Render() string
}

type Checkbox interface {
    Check() string
}

// 추상 팩토리 인터페이스
type GUIFactory interface {
    CreateButton() Button
    CreateCheckbox() Checkbox
}

각 구체적인 factory는 서로 관련된 구성 요소 family를 생성합니다:

// Windows 계열
type WindowsButton struct{}
func (w WindowsButton) Render() string { return "Windows Button" }

type WindowsCheckbox struct{}
func (w WindowsCheckbox) Check() string { return "Windows Checkbox" }

type WindowsFactory struct{}
func (w WindowsFactory) CreateButton() Button { return WindowsButton{} }
func (w WindowsFactory) CreateCheckbox() Checkbox { return WindowsCheckbox{} }

// Mac 계열
type MacButton struct{}
func (m MacButton) Render() string { return "Mac Button" }

type MacCheckbox struct{}
func (m MacCheckbox) Check() string { return "Mac Checkbox" }

type MacFactory struct{}
func (m MacFactory) CreateButton() Button { return MacButton{} }
func (m MacFactory) CreateCheckbox() Checkbox { return MacCheckbox{} }

클라이언트 코드는 팩토리 interface와 함께 작동하며, 구체적인 구현과는 독립적으로 유지됩니다.

func BuildUI(factory GUIFactory) {
    button := factory.CreateButton()
    checkbox := factory.CreateCheckbox()
    fmt.Println(button.Render(), checkbox.Check())
}

시스템이 서로 관련된 여러 제품 family와 함께 작동해야 하고 동일한 family의 구성 요소가 함께 사용되도록 보장하려면 Abstract Factory를 사용하세요. 간단한 Factory보다 복잡하므로 제품 family를 실제로 관리해야 할 때만 사용하세요.

challenge icon

챌린지

쉬움

Abstract Factory 패턴을 사용하여 가구 매장 시스템을 만들어 봅시다! 서로 관련된 가구 items의 family를 생산하는 factory를 만들게 됩니다. 각 factory는 일관된 스타일(Modern 또는 Vintage)을 생산하므로, 같은 factory에서 나온 의자와 테이블은 미적으로 서로 어울립니다.

코드를 세 개의 파일로 구성합니다.

  • furniture.go: 제품 인터페이스와 구체적인 가구 유형을 Define합니다.

    두 개의 제품 인터페이스를 Create합니다.

    • Chair 및 메서드 SitOn() string
    • Table 및 메서드 PlaceItems() string

    두 family의 가구를 implement합니다.

    • Modern family: ModernChairSitting on a sleek modern chair를 반환하고, ModernTablePlacing items on a glass modern table을 반환합니다.
    • Vintage family: VintageChairSitting on an ornate vintage chair를 반환하고, VintageTablePlacing items on a wooden vintage table을 반환합니다.
  • factory.go: abstract factory 인터페이스와 구체적인 factory를 Define합니다.

    두 개의 메서드를 가진 FurnitureFactory 인터페이스를 Create합니다.

    • CreateChair() Chair
    • CreateTable() Table

    두 개의 구체적인 factory를 implement합니다.

    • ModernFactoryModernChairModernTable을 생산합니다.
    • VintageFactoryVintageChairVintageTable을 생산합니다.

    또한 스타일(modern 또는 vintage)에 따라 appropriate factory를 반환하는 GetFactory(style string) FurnitureFactory function을 Create합니다. 인식할 수 없는 스타일에는 ModernFactory를 Default로 사용합니다.

  • main.go: factory를 사용하여 방을 Furnish합니다.

    factory를 사용하여 의자와 테이블을 Create한 다음, 두 actions를 separate lines에 formatted하여 보여 주는 문자열을 반환하는 FurnishRoom(factory FurnitureFactory) string function을 Create합니다.

    스타일 입력을 읽고, appropriate factory를 가져온 다음, 방을 Furnish하고 결과를 출력합니다.

다음 입력이 제공됩니다.

  • Line 1: 가구 스타일(modern, vintage 또는 다른 값)

예를 들어 다음과 같이 주어졌을 때:

modern

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

Sitting on a sleek modern chair
Placing items on a glass modern table

또한 다음과 같이 주어졌을 때:

vintage

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

Sitting on an ornate vintage chair
Placing items on a wooden vintage table

그리고 다음과 같이 주어졌을 때:

rustic

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

Sitting on a sleek modern chair
Placing items on a glass modern table

FurnishRoom function이 인터페이스를 통해 어떤 factory와도 함께 작동하는 방식을 확인하세요. 이 function은 modern 가구를 creating하는지 vintage 가구를 creating하는지 알지 못합니다. 이를 통해 방의 모든 가구가 동일한 family에서 나오도록 하여 일관된 스타일을 유지합니다!

직접 해보기

package main

import "fmt"

// FurnishRoom은 팩토리를 사용하여 가구를 만들고 결과를 반환합니다
// TODO: 이 함수를 구현하세요
// - 팩토리를 사용하여 의자와 테이블을 만드세요
// - 첫 번째 줄에 SitOn() 결과, 두 번째 줄에 PlaceItems() 결과가 있는 문자열을 반환하세요
func FurnishRoom(factory FurnitureFactory) string {
	// TODO: 팩토리를 사용하여 의자와 테이블을 만드세요
	// TODO: 두 동작을 별도의 줄에 담은 형식화된 문자열을 반환하세요
	return ""
}

func main() {
	var style string
	fmt.Scanln(&style)

	// TODO: style에 따라 적절한 팩토리를 가져오세요
	// TODO: 팩토리를 사용하여 방을 꾸미세요
	// TODO: 결과를 출력하세요
}
quiz icon실력 점검

이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.

객체 지향 프로그래밍의 모든 레슨

직접 연습해 보세요: 온라인 Go 컴파일러