추상 팩토리 패턴
Coddy GO 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨 — 107개 중 88번째.
추상 팩토리 패턴(Abstract Factory pattern)은 구체적인 타입을 명시하지 않고 관련된 객체들의 군을 생성함으로써 팩토리 패턴을 확장합니다. 단일 팩토리 함수 대신 팩토리 인터페이스를 정의하며, 여러 구체적인 팩토리들이 이를 구현하여 각각 일관된 관련 객체 세트를 생성합니다.
버튼과 체크박스를 생성해야 하는 UI 툴킷을 생각해 봅시다. 운영 체제마다 서로 다른 구현이 필요하지만, 컴포넌트들은 일관되게 함께 작동해야 합니다:
type Button interface {
Render() string
}
type Checkbox interface {
Check() string
}
// 추상 팩토리 인터페이스
type GUIFactory interface {
CreateButton() Button
CreateCheckbox() Checkbox
}각 구체 팩토리는 연관된 컴포넌트 제품군을 생성합니다:
// 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{} }클라이언트 코드는 팩토리 인터페이스와 함께 작동하며, 구체적인 구현체로부터 독립성을 유지합니다:
func BuildUI(factory GUIFactory) {
button := factory.CreateButton()
checkbox := factory.CreateCheckbox()
fmt.Println(button.Render(), checkbox.Check())
}시스템이 여러 관련 제품군과 함께 작동해야 하고 동일한 제품군의 컴포넌트가 함께 사용되도록 보장하려는 경우 Abstract Factory를 사용하세요. 이는 단순한 Factory보다 복잡하므로 제품군을 관리해야 할 실제 필요가 있을 때만 사용하십시오.
챌린지
쉬움추상 팩토리(Abstract Factory) 패턴을 사용하여 가구점 시스템을 구축해 봅시다! 여러분은 연관된 가구 아이템 제품군을 생산하는 팩토리를 만들게 됩니다. 각 팩토리는 일관된 스타일(Modern 또는 Vintage)을 생산하여, 동일한 팩토리에서 만들어진 의자와 테이블이 미적으로 서로 어울리도록 보장합니다.
코드는 다음 세 개의 파일로 구성됩니다:
furniture.go: 제품 인터페이스와 구체적인 가구 타입을 정의합니다.두 개의 제품 인터페이스를 생성하세요:
SitOn() string메서드를 가진ChairPlaceItems() string메서드를 가진Table
두 가지 가구 제품군을 구현하세요:
- Modern 제품군:
ModernChair는Sitting on a sleek modern chair를 반환하고,ModernTable은Placing items on a glass modern table을 반환합니다. - Vintage 제품군:
VintageChair는Sitting on an ornate vintage chair를 반환하고,VintageTable은Placing items on a wooden vintage table을 반환합니다.
factory.go: 추상 팩토리 인터페이스와 구체적인 팩토리들을 정의합니다.두 개의 메서드를 가진
FurnitureFactory인터페이스를 생성하세요:CreateChair() ChairCreateTable() Table
두 개의 구체적인 팩토리를 구현하세요:
ModernChair와ModernTable을 생산하는ModernFactoryVintageChair와VintageTable을 생산하는VintageFactory
또한 스타일에 따라 적절한 팩토리를 반환하는
GetFactory(style string) FurnitureFactory함수를 만드세요 (modern또는vintage). 인식되지 않는 스타일의 경우 기본값으로ModernFactory를 반환합니다.main.go: 팩토리를 사용하여 방을 꾸밉니다.팩토리를 사용하여 의자와 테이블을 생성한 후, 두 동작을 별도의 줄에 표시하는 형식화된 문자열을 반환하는
FurnishRoom(factory FurnitureFactory) string함수를 생성하세요.스타일 입력을 읽고, 적절한 팩토리를 가져와서 방을 꾸미고 결과를 출력하세요.
다음과 같은 입력이 제공됩니다:
- 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 함수가 인터페이스를 통해 모든 팩토리와 어떻게 작동하는지 주목하세요. 이 함수는 현대적인 가구를 만드는지 빈티지 가구를 만드는지 알지 못합니다. 이를 통해 방 안의 모든 가구가 동일한 제품군에서 생산되어 일관된 스타일을 유지할 수 있습니다!
치트 시트
Abstract Factory 패턴은 구체적인 타입을 명시하지 않고 관련된 객체들의 패밀리를 생성합니다. 이는 여러 구체적인 팩토리가 구현하는 팩토리 인터페이스를 정의하며, 각 팩토리는 일관된 관련 객체 세트를 생성합니다.
구조
각 객체 유형에 대한 제품 인터페이스를 정의합니다:
type Button interface {
Render() string
}
type Checkbox interface {
Check() string
}각 제품 유형을 생성하기 위한 메서드를 선언하는 추상 팩토리 인터페이스를 생성합니다:
type GUIFactory interface {
CreateButton() Button
CreateCheckbox() Checkbox
}구체적인 구현
각 패밀리가 일관된 스타일이나 동작을 갖는 구체적인 제품 패밀리를 구현합니다:
// 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{} }클라이언트 코드
클라이언트 코드는 팩토리 인터페이스와 함께 작동하며, 구체적인 구현과는 독립적으로 유지됩니다:
func BuildUI(factory GUIFactory) {
button := factory.CreateButton()
checkbox := factory.CreateCheckbox()
fmt.Println(button.Render(), checkbox.Check())
}사용 시기
시스템이 관련된 제품의 여러 패밀리와 함께 작동해야 하고, 동일한 패밀리의 컴포넌트들이 함께 사용되도록 보장하고 싶을 때 Abstract Factory를 사용하세요. 이는 단순한 Factory보다 복잡하므로, 제품 패밀리를 관리해야 할 실제 필요가 있을 때만 사용하십시오.
직접 해보기
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: 스타일에 따른 적절한 팩토리를 가져오세요
// TODO: 팩토리를 사용하여 방을 꾸미세요
// TODO: 결과를 출력하세요
}
이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.
객체 지향 프로그래밍의 모든 레슨
8에러 처리와 OOP
error 인터페이스사용자 정의 에러 타입에러 래핑 (fmt.Errorf)센티넬 에러errors.Is()와 errors.As()Panic, Defer, Recover요약 - 파일 파서