Abstract Factory Pattern
Overview
제품 군을 만드는데 유용한 패턴.
When to use
그룹 단위의 여러 구성요소 객체를 만들어야 할 때
How to use
- Product 를 정의한다.
 - Product 의 구성 요소가 많다. -> Abstract factory 패턴 적용 신호
 - 구성 요소를 정의한다.
 - 구성 요소를 생성하는 Abstract factory 인터페이스 또는 추상 클래스를 정의한다.
 - Abstract factory 에게 Product 구성 요소 생성을 위임한다.
 
Element
각 그룹의 구성요소.
- Button
 - Window Button
 - Mac Button
 - Checkbox
 - Windows Checkbox
 - Mac Checkbox
 
public interface Button {
  void click();
}
public class WindowsButton implements Button {
  @Override
  public void click() {
    System.out.println("Windows button clicked");
  }
}
public class MacButton implements Button {
  @Override
  public void click() {
    System.out.println("Mac button clicked");
  }
}
public interface CheckBox {
  void click();
}
public class WindowsCheckBox implements CheckBox {
  @Override
  public void click() {
    System.out.println("Windows checkbox clicked");
  }
}
public class MacCheckBox implements CheckBox {
  @Override
  public void click() {
    System.out.println("Mac checkbox clicked");
  }
}
Product Factory
Abstract Factory 인터페이스 
각각의 구성 요소(Button, CheckBox) 생성 역할 담당.
- GUIFactory
 - Windows GUI Factory
 - Mac GUI Factory
 
public interface GUIFactory {
  Button createButton();
  CheckBox createCheckbox();
}
public class WindowsGuiFactory implements GUIFactory {
  @Override
  public Button createButton() {
    return new WindowsButton();
  }
  @Override
  public CheckBox createCheckbox() {
    return new WindowsCheckBox();
  }
}
public class MacGuiFactory implements GUIFactory {
  @Override
  public Button createButton() {
    return new MacButton();
  }
  @Override
  public CheckBox createCheckbox() {
    return new MacCheckBox();
  }
}
Product
객체의 '사용'부분만 신경씀. 
'구성요소 생성' (그룹군) 은 Factory 에게 위임.
- GUI
 - Windows GUI
 - Mac GUI
 
public interface GUI {
  void display();
}
@RequiredArgsConstructor
public class WindowsGui {
  private final Button button;
  private final CheckBox checkBox;
  public WindowsGui(GuidFactory factory) {
    this.button = factory.createButton();
    this.checkBox = factory.createCheckBox();
  }
  public void display() {
    System.out.println("showing windows button and checkbox..");
  }
}
@RequiredArgsConstructor
public class  MacGui {
  private final Button button;
  private final CheckBox checkBox;
  public MacGui(GuidFactory factory) {
    this.button = factory.createButton();
    this.checkBox = factory.createCheckBox();
  }
  public void display() {
    System.out.println("showing mac button and checkbox..");
  }
}
Conclusion
Product 가 구성 요소를 어떻게 조합할지 모른 체, 제품을 정의할 수 있게되었다.
정보
Product 객체 사용에만 관심을 갖고, 구성 요소 생성은 Factory 로 위임했다. 
구성 요소 추가, 변경은 오로지 Factory 에서만 이뤄진다.
이로써 WindowsGUI, MacGUI 제품의 Button, CheckBox 를 유연하게 구성할 수 있게됐다. 
Abstract factory 패턴이 없다면 다음과 같이 구성요소를 의미하는 Product 클래스가 지속적으로 늘어날 수도 있다.
- WindowsButtonMacCheckBoxGUI
 - WindowsButtonWindowsCheckBoxGUI
 - MacButtonMacCheckBoxGUI
 - MacButtonWindowsCheckBoxGUI
 
즉, 구성요소가 하나 늘어날 때마다 사용보다 '생성' 조합을 의미하는 클래스가 늘어날 수 있다. 
클래스 개수 == 기본 Product 수 * Element 수