사용 의도
- 서로 관련성이 있거나, 독립적인 여러 객체를 생성하기 위한 인터페이스를 제공합니다.
- 아래의 설명에서는 서로 관련성이 있는 경우에 객체를 생성하는 인터페이스를 제공하는 예시를 통해 추상팩토리 패턴을 설명해보겠습니다.
예시) 화이트모드와 다크모드 개발
- 기획자에게 화이트모드와 다크모드의 경우에 달라지는 화면을 만들어달라는 요구를 받았습니다.
화이트모드 | 다크모드 |
배경화면의 색상이 흰색이어야 한다. | 배경화면의 색상이 검은색이어야 한다. |
제공되는 폰트는 BOLD 여야 하며, 크기는 10이어야한다. | 제공되는 폰트는 ITALIC 이어야 하며, 크기는 12여야한다. |
이를 위해 개발자 A는 아래와 같이 클래스를 구성한 뒤, 화면클래스를 반환하도록 하였습니다.
- 화면 클래스 (Window)
- 폰트 클래스 (Font)
- 배경화면 클래스 (Background)
public class Window {
private Font font;
private Color color;
public void setFont(Font font) {
this.font = font;
}
public void setColor(Color color) {
this.color = color;
}
}
생성 측에서, 아래와같은 코드가 되겠네요
public class WindowCreator {
public Window createWindow(Mode mode) {
Window window = new Window();
switch (mode) {
case DARK:
Font font = new Font();
font.setSize(10);
font.setType(Type.BOLD);
window.setFont(font);
Background background = new Background();
background.setColor(Color.WHITE);
window.setBackground(background);
case WHITE:
Font font2 = new Font();
font2.setSize(12);
font2.setType(Type.ITALIC);
window.setFont(font2);
Background background2 = new Background();
background2.setColor(Color.BLACK);
window.setBackground(background2);
}
return window;
}
}
개발을 마친뒤에, API 스펙을 해당 개발자는 공개했고 성황리에 사용됐습니다.
- 하지만 업데이트를 통해 기획서가 변경되었습니다.
화이트모드 | 다크모드 |
배경화면의 색상이 흰색이어야 한다. | 배경화면의 색상이 검은색->회색이어야 한다. |
제공되는 폰트는 BOLD->ITALIC 여야 하며, 크기는 10이어야한다. | 제공되는 폰트는 ITALIC->BOLD 이어야 하며, 크기는 12여야한다. |
이러한 경우에 클라이언트측의 코드는 아래와 같이 변경될것입니다.
- 이러한 경우의 단점은 2가지로 볼 수 있습니다.
- Creator 쪽의 코드가 복잡해진다.
- 모드가 출시될 때마다, 코드가 증가하는 단점
- 다크모드 / 화이트모드가 변경되는 경우, Creator 측의 코드가 수정되어야한다.
- 변경에 유연하지 못하게됩니다.
- Creator 쪽의 코드가 복잡해진다.
public class WindowCreator {
public Window createWindow(Mode mode) {
Window window = new Window();
switch (mode) {
case DARK:
Font font = new Font();
font.setSize(10);
font.setType(Type.ITALIC); // changed
window.setFont(font);
...
case WHITE:
Font font2 = new Font();
font2.setSize(12);
font2.setType(Type.BOLD); // changed
window.setFont(font2);
Background background2 = new Background();
background2.setColor(Color.GRAY); // changed
window.setBackground(background2);
}
return window;
}
}
모드가 변경되었는데 Creator 측의 코드를 변경해야하는 일이 일어났고, 개발자 A는 화가나버렸습니다.
또한 모드가 만약 많고, 기획서가 대규모로 변경되면 더 많이 변경해야 한다는 생각이 들어버린 개발자 A는 퇴사를해버렸습니다.
개발자 B는 추상팩토리를 이용하여 아래와 같이 클래스구조를 구성하였습니다.
배경화면
public abstract class Background {
public abstract Color getColor();
}
public class BlackBackground extends Background {
@Override
public Color getColor() {
return Color.BLACK;
}
}
public class WhiteBackground extends Background {
@Override
public Color getColor() {
return Color.WHITE;
}
}
폰트
public abstract class Font {
public abstract int getSize();
public abstract Type getType();
}
public class BlackFont extends Font {
@Override
public int getSize() {
return 10;
}
@Override
public Type getType() {
return Type.BOLD;
}
}
public class WhiteFont extends Font {
@Override
public int getSize() {
return 12;
}
@Override
public Type getType() {
return Type.ITALIC;
}
}
팩토리
public abstract class WindowFactory {
public abstract Background createBackground();
public abstract Font createFont();
}
public class BlackWindowFactory extends WindowFactory {
@Override
public Background createBackground() {
return new BlackBackground();
}
@Override
public Font createFont() {
return new BlackFont();
}
}
public class WhiteWindowFactory extends WindowFactory {
@Override
public Background createBackground() {
return new WhiteBackground();
}
@Override
public Font createFont() {
return new WhiteFont();
}
}
생성
public class WindowCreator {
public Window createWindow(WindowFactory windowFactory) {
final Window window = new Window();
final Background background = windowFactory.createBackground();
final Font font = windowFactory.createFont();
window.setBackground(background);
window.setFont(font);
return window;
}
}
위의 경우에는, 기획안이 변경됨에 따라서 Creator 부분은 전혀 변경되지 않습니다.
- 화이트모드의 폰트의 크기가 변경되면 BlackFont 클래스를 변경하면되며
- 다크모드의 배경화면 색상이 변경되면 WhiteBackground 클래스를 변경하면됩니다.
- 또한 새로운 모드(옐로우 모드) 가 추가될 시에도 Creator 부분은 변경이 되지 않습니다.
장점은 아래와 같습니다.
※ 클래스의 생성과 구현클래스의 책임이 분리됩니다.
※ Creator에는 font 사이즈가 몇인지, 타입은 무엇인지 등에 대한 정보가 노출되지 않습니다. (캡슐화)
※ 변경에 유연합니다.
'디자인패턴' 카테고리의 다른 글
브릿지 패턴 (Bridge Pattern) (0) | 2021.06.18 |
---|---|
어댑터 패턴 (Adapter pattern) (0) | 2021.06.12 |
단일체 패턴 (Singleton Pattern) (0) | 2021.06.05 |
원형패턴 (Prototype Pattern) (0) | 2021.06.03 |
팩토리 메서드 패턴 (Factory Method Pattern) (0) | 2021.05.29 |