추상 팩토리 패턴

**추상 팩토리 패턴**(Abstract factory pattern)은 다양한 구성 요소 별로 '객체의 집합'을 생성해야 할 때 유용하다. 이 패턴을 사용하여 상황에 알맞은 객체를 생성할 수 있다. 대표적인 예로, 자바 프로그래밍 언어의 GUI 구성 요소인 AWT/Swing 라이브러리의 룩 앤드 필 변경 기능을 들 수 있다. 메탈, 마이크로소프트 윈도우, 맥 OS 등의 모양으로 변경할 수 있다. 이에 따라 추상 팩토리에 있는 기본 팩토리 객체가 변경된다. 그러면 이후로 생성되는 GUI 객체들은 전부 해당 룩앤필에 따른다.
# 구조

## UML 클래스 및 시퀀스 다이어그램
accessdate=2017-08-12
## 클래스 다이어그램
left -
## UML 클래스 다이어그램
left -
## Lepus3 차트 (범례)
left -
# C # 예제
interface IButton { void Paint(); } interface IGUIFactory { IButton CreateButton(); } class WinFactory : IGUIFactory { public IButton CreateButton() { return new WinButton(); } } class OSXFactory : IGUIFactory { public IButton CreateButton() { return new OSXButton(); } } class WinButton : IButton { public void Paint() { //Render a button in a Windows style } } class OSXButton : IButton { public void Paint() { //Render a button in a Mac OS X style } } class Program { static void Main() { var appearance = Settings.Appearance; IGUIFactory factory; switch (appearance) { case Appearance.Win: factory = new WinFactory(); break; case Appearance.OSX: factory = new OSXFactory(); break; default: throw new System.NotImplementedException(); } var button = factory.CreateButton(); button.Paint(); } }
# Golang 예제
package main import ( "fmt" ) type Button interface { Paint() } type GUIFactory interface { CreateButton() Button } type WinFactory struct{} func (f *WinFactory) CreateButton() Button { return new(WinButton) } type OSXFactory struct{} func (f *OSXFactory) CreateButton() Button { return new(OSXButton) } type LinuxFactory struct{} func (f *LinuxFactory) CreateButton() Button { return new(LinuxButton) } type WinButton struct{} func (b *WinButton) Paint() { fmt.Println("WinButton") } type OSXButton struct{} func (b *OSXButton) Paint() { fmt.Println("OSXButton") } type LinuxButton struct{} func (b *LinuxButton) Paint() { fmt.Println("LinuxButton") } func BuildFactory(appearance string) GUIFactory { switch appearance { case "Window": return new(WinFactory) case "OSX": return new(OSXFactory) case "Linux": return new(LinuxFactory) } return nil } func main() { if factory := BuildFactory("Window"); factory != nil { winButton := factory.CreateButton() winButton.Paint() } if factory := BuildFactory("OSX"); factory != nil { osxButton := factory.CreateButton() osxButton.Paint() } if factory := BuildFactory("Linux"); factory != nil { linuxButton := factory.CreateButton() linuxButton.Paint() } }
# Python 예제
import enum from abc import * class Button: @abstractmethod def Paint(self): pass class MousePointer: @abstractmethod def Paint(self): pass class GUIFactory: @abstractmethod def CreateButton(self): return Button @abstractmethod def CreateMousePointer(self): return MousePointer class WinFactory(GUIFactory): def CreateButton(self): return WinButton() def CreateMousePointer(self): return WinMousePointer() class OSXFactory(GUIFactory): def CreateButton(self): return OSXButton() def CreateMousePointer(self): return OSXMousePointer() class WinMousePointer(MousePointer): def Paint(self): print("Render a mousepointer in a Windows style") class OSXMousePointer(MousePointer): def Paint(self): print ("Render a mousepointer in a OSX style") class WinButton(Button): def Paint(self): print ("Render a button in a Windows style") class OSXButton(Button): def Paint(self): print ("Render a button in a Mac OSX style") class Settings: @staticmethod def Default(): return Appearance.WIN class Appearance(enum.Enum): WIN = 0 OSX = 1 def main(): apperance = Settings.Default() if apperance == Appearance.WIN: factory = WinFactory() elif apperance == Appearance.OSX: factory = OSXFactory() button = factory.CreateButton() mousePointer = factory.CreateMousePointer() button.Paint() mousePointer.Paint() if __name__
# '__main__': main()
PHP 예제 == interface Button { public function paint(); } interface GUIFactory { public function createButton(): Button; } class WinFactory implements GUIFactory { public function createButton(): Button { return new WinButton(); } } class OSXFactory implements GUIFactory { public function createButton(): Button { return new OSXButton(); } } class WinButton implements Button { public function paint() { echo "Windows Button"; } } class OSXButton implements Button { public function paint() { echo "OSX Button"; } } $appearance = "osx"; $factory = NULL; switch ($appearance) { case "win": $factory = new WinFactory(); break; case "osx": $factory = new OSXFactory(); break; default: break; } if ($factory instanceof GUIFactory) { $button = $factory->createButton(); $button->paint(); }