추상 팩토리 패턴
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를 실제로 관리해야 할 때만 사용하세요.
챌린지
쉬움Abstract Factory 패턴을 사용하여 가구 매장 시스템을 만들어 봅시다! 서로 관련된 가구 items의 family를 생산하는 factory를 만들게 됩니다. 각 factory는 일관된 스타일(Modern 또는 Vintage)을 생산하므로, 같은 factory에서 나온 의자와 테이블은 미적으로 서로 어울립니다.
코드를 세 개의 파일로 구성합니다.
furniture.go: 제품 인터페이스와 구체적인 가구 유형을 Define합니다.두 개의 제품 인터페이스를 Create합니다.
Chair및 메서드SitOn() stringTable및 메서드PlaceItems() string
두 family의 가구를 implement합니다.
- Modern family:
ModernChair는Sitting on a sleek modern chair를 반환하고,ModernTable은Placing items on a glass modern table을 반환합니다. - Vintage family:
VintageChair는Sitting on an ornate vintage chair를 반환하고,VintageTable은Placing items on a wooden vintage table을 반환합니다.
factory.go: abstract factory 인터페이스와 구체적인 factory를 Define합니다.두 개의 메서드를 가진
FurnitureFactory인터페이스를 Create합니다.CreateChair() ChairCreateTable() Table
두 개의 구체적인 factory를 implement합니다.
ModernFactory는ModernChair와ModernTable을 생산합니다.VintageFactory는VintageChair와VintageTable을 생산합니다.
또한 스타일(
modern또는vintage)에 따라 appropriate factory를 반환하는GetFactory(style string) FurnitureFactoryfunction을 Create합니다. 인식할 수 없는 스타일에는ModernFactory를 Default로 사용합니다.main.go: factory를 사용하여 방을 Furnish합니다.factory를 사용하여 의자와 테이블을 Create한 다음, 두 actions를 separate lines에 formatted하여 보여 주는 문자열을 반환하는
FurnishRoom(factory FurnitureFactory) stringfunction을 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 tableFurnishRoom 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: 결과를 출력하세요
}
이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.
객체 지향 프로그래밍의 모든 레슨
8에러 처리와 OOP
error 인터페이스사용자 정의 에러 타입에러 래핑 (fmt.Errorf)센티넬 에러errors.Is()와 errors.As()Panic, Defer, Recover요약 - 파일 파서직접 연습해 보세요: 온라인 Go 컴파일러