추상 팩토리 패턴

추상 팩토리 패턴(Abstract factory pattern)은 다양한 구성 요소 별로 '객체의 집합'을 생성해야 할 때 유용하다. 이 패턴을 사용하여 상황에 알맞은 객체를 생성할 수 있다.
대표적인 예로, 자바 프로그래밍 언어의 GUI 구성 요소인 AWT/Swing 라이브러리의 룩 앤드 필 변경 기능을 들 수 있다. 메탈, 마이크로소프트 윈도우, 맥 OS 등의 모양으로 변경할 수 있다. 이에 따라 추상 팩토리에 있는 기본 팩토리 객체가 변경된다. 그러면 이후로 생성되는 GUI 객체들은 전부 해당 룩앤필에 따른다.
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
func (f *WinFactory) CreateButton() Button {
 return new(WinButton)
func (f *OSXFactory) CreateButton() Button {
 return new(OSXButton)
func (f *LinuxFactory) CreateButton() Button {
 return new(LinuxButton)
func (b *WinButton) Paint() {
 fmt.Println("WinButton")
func (b *OSXButton) Paint() {
 fmt.Println("OSXButton")
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-&gt;createButton();
 $button-&gt;paint();