- Abstract Factory Pattern provides a way to encapsulate a group of individual factories that have a common theme
public abstract class ThemeFactory
abstract IFontStyle createFontStyle();
abstract IFontSize createFontSize();
------------------------------------------------------------------------
public class ThemeA extends ThemeFactory
IFontStyle createFontStyle() {
return new Bold();
}
IFontSize createFontSize() {
Return new Size8();
}
------------------------------------------------------------------------
public class ThemeB extends ThemeFactory
@Override
IFontStyle createFontStyle() {
return new Underline();
}
@Override
IFontSize createFontSize() {
return new Size10();
}
------------------------------------------------------------------------
public interface IFontStyle {
public String getStyle(); }
------------------------------------------------------------------------
public class Bold implements IFontStyle
public String getStyle() {
return "Bold";
}
------------------------------------------------------------------------
public class Underline implements IFontStyle
public String getStyle() {
return "Underline";
}
------------------------------------------------------------------------
public interface IFontSize
public String getSize();
------------------------------------------------------------------------
public class Size8 implements IFontSize
@Override
public String getSize() {
return "8pt";
}
------------------------------------------------------------------------
public class Size9 implements IFontSize
public String getSize() {
return "9pt";
}
------------------------------------------------------------------------
public class ClientNotePad
private IFontSize fontSize;
private IFontStyle fontStyle;
public ClientNotePad(ThemeFactory themeFactory) {
this.fontSize = themeFactory.createFontSize();
this.fontStyle = themeFactory.createFontStyle();
}
public void print() {
System.out.println("FontStyle[" + this.fontStyle.getStyle() + "]"); // [Bold] or [Underline]
System.out.println("FontSize[" + this.fontSize.getSize() + "]"); // [8pt] or [9pt]
}
public static void main(String[] args) {
System.out.println("ThemeA");
ClientNotePad testThemeA = new ClientNotePad(new ThemeA());
testThemeA.print();
System.out.println("ThemeB");
ClientNotePad testThemeB = new ClientNotePad(new ThemeB());
testThemeB.print();
}
- 응용
- Factory 객체를 하나만 생성및 유지하는 방법
- 개요 : ThemeA와 ThemeB중 어느 하나의 객체만 생성해서 사용하면 되고, 이 객체는 전체 프로그램에서 두 개 이상 존재할 필요가 없고, 특정 객체를 하나만 생성하게 명백히 보장하고 싶을 경우 방법
- 방법 : Singleton Pattern을 사용한다. ClientNotePad부분을 Singleton으로 만들면 소스상에서 분기해서 ThemeA와 ThemeB중에 하나를 생성되도록 변경해야한다. 그러면 추후 ThemeC를 추가할때 소스를 수정해야 하므로 ThemeFactory에 abstract createInstance 메소드를 넣고, ThemeA와 ThemeB에서 각각 createInstalce()를 구현하게 하면 추후 소스수정이 없다.
- Theme가 추가될때마다 Factory의 자식 클래스를 생성하지 않는 방법
- 개요 : Theme가 늘어날 때마다 ThemeA및 ThemeB와 같은 클래스들을 구현해야하는 불편을 줄이고 싶을때
- 방법 : IFontStyle및 IFontSize에 abstract clone()를 넣고 각각의 Bold, Underline, Size8, Size9에서 객체를 복사하는 clone()를 구현하고 ThemeFactory의 생성자에서 IFontStyle과 IFontSize를 받도록 구현하고, ClientNotePad에서 Bold bold; Size8 size8; new ThemeFactory(bold, size8)의 형식과 같이 호출한다. reflection을 써도 될것 같다.
- 기타
- ThemeFactory에는 생산해야하는 종류(FontStyle, FontSize)가 abstract method나 virture method로 선언되어 있어야 한다.