추상 팩토리 패턴이란 서로 관련이 있는 객체들을 통째로 묶어서 팩토리 클래스로 만들고, 이들 팩토리를 조건에 따라 생성하도록 다시 팩토리를 만들어서 객체를 생성하는 패턴이다.
추상 팩토리 패턴은 객체를 찍어내는 공장(팩토리)에게 객체의 생성을 위임한다는 점에서 팩토리 메서드 패턴과 유사하지만 그 구조에서 약간의 차이가 있다.
팩토리 메서드 패턴: 각각 다른 객체들이 필요할 때 사용
추상 팩토리 패턴: 서로 연관있는 객체들의 조합이 필요할 때 사용
예를 들어, 컴퓨터 객체를 생성하여 반환하는 팩토리가 있을 때, 삼성 컴퓨터와 LG 컴퓨터 두 개의 옵션이 있다면 각 패턴의 흐름은 다음과 같다.
// Keyboard 객체 정의
public interface Keyboard {
}
// SamsungKeyboard
public class SamsungKeyboard implements Keyboard {
public SamsungKeyboard() {
System.out.println("Creating Samsung keyboard...");
}
}
// LGKeyboard
public class LGKeyboard implements Keyboard {
public LGKeyboard() {
System.out.println("Creating LG keyboard...");
}
}
// Mouse 객체 정의
public interface Mouse {
}
// SamsungMouse
public class SamsungMouse implements Mouse {
public SamsungMouse() {
System.out.println("Creating Samsung mouse...");
}
}
// LGMouse
public class LGMouse implements Mouse {
public LGMouse() {
System.out.println("Creating LG mouse...");
}
}
// Keyboard 팩토리 생성
public class KeyboardFactory {
public Keyboard createKeyboard(String type) {
Keyboard keyboard = null;
switch (type) {
case "Samsung":
keyboard = new SamsungKeyboard();
break;
case "LG":
keyboard = new LGKeyboard();
break;
}
return keyboard;
}
}
// Mouse 팩토리 생성
public class MouseFactory {
public Mouse createMouse(String type) {
Mouse mouse = null;
switch (type) {
case "Samsung":
mouse = new SamsungMouse();
break;
case "LG":
mouse = new LGMouse();
break;
}
return mouse;
}
}
// Computer 팩토리 생성
public class ComputerFactory {
public void createComputer(String type) {
KeyboardFactory keyboardFactory = new KeyboardFactory();
keyboardFactory.createKeyboard(type);
MouseFactory mouseFactory = new MouseFactory();
mouseFactory.createMouse(type);
}
}
// Client 요청
public class Client {
public static void main(String[] args) {
ComputerFactory computerFactory = new ComputerFactory();
computerFactory.createComputer("Samsung");
}
}
팩토리 메서드 패턴에서는 위와 같이 ComputerFactory가 클라이언트의 요청을 받아서 KeyboardFactory와 MosueFactory에게 각각 Keyboard와 Mouse 객체를 생성하도록 메시지를 전달한다.
하지만 컴퓨터의 구성품이 모니터, 스피커 등 늘어날 수록 정의해야 하는 Factory의 수가 늘어날 것이고 객체 생성 메서드의 길이는 늘어나게 된다.
그러나 Samsung 컴퓨터의 경우 모든 구성품은 Samsung의 제품 객체로 이뤄질 것이고 LG의 경우 LG의 제품으로 이줘질 것이다.
이 때, 추상 팩토리 패턴에서는 연관있는 객체들을 조합하여 Factory 클래스를 정의한다(Samsung은 Samsung끼리, LG는 LG끼리).
// Keyboard와 Mouse 객체는 동일 하다
// Keyboard 객체 정의
public interface Keyboard {
}
// SamsungKeyboard
public class SamsungKeyboard implements Keyboard {
public SamsungKeyboard() {
System.out.println("Creating Samsung keyboard...");
}
}
// LGKeyboard
public class LGKeyboard implements Keyboard {
public LGKeyboard() {
System.out.println("Creating LG keyboard...");
}
}
// Mouse 객체 정의
public interface Mouse {
}
// SamsungMouse
public class SamsungMouse implements Mouse {
public SamsungMouse() {
System.out.println("Creating Samsung mouse...");
}
}
// LGMouse
public class LGMouse implements Mouse {
public LGMouse() {
System.out.println("Creating LG mouse...");
}
}
// ComputerFactory 정의
public interface ComputerFactory {
public Keyboard creatKeyboard();
public Mouse createMouse();
}
// SamsungComputerFactory 정의
public class SamsungComputerFactory implements ComputerFactory {
@Override
public Keyboard creatKeyboard() {
return new SamsungKeyboard();
}
@Override
public Mouse createMouse() {
return new SamsungMouse();
}
}
// LGComputerFactory 정의
public class LGComputerFactory implements ComputerFactory {
@Override
public Keyboard creatKeyboard() {
return new LGKeyboard();
}
@Override
public Mouse createMouse() {
return new LGMouse();
}
}
// FactoryOfComputerFactory 정의
public class FactoryOfComputerFactory {
public void createComputer(String type) {
ComputerFactory computerFactory = null;
switch (type) {
case "Samsung":
computerFactory = new SamsungComputerFactory();
break;
case "LG":
computerFactory = new LGComputerFactory();
}
computerFactory.creatKeyboard();
computerFactory.createMouse();
}
}
// Client 요청
public class Client {
public static void main(String[] args) {
FactoryOfComputerFactory FactoryOfcomputerFactory = new FactoryOfComputerFactory();
FactoryOfcomputerFactory.createComputer("LG");
}
}
추상 팩토리 패턴에서는 위와 같이 각 제조사(Samsung, LG)별로 부품(Keyboard, Mouse)들을 조합하여 각 회사의 컴퓨터를 생산하는 공장(SamsungComputerFactory, LGComputerFactory)을 만든다.
각 컴퓨터 공장은 ComputerFactory(추상 팩토리 패턴에서는 interface)에 선언된 각 부품을 생산하는 메소드(createKeyboard, createMouse)를 오버라이드해서 정의하고 각 공장의 부품들을 생산하여 컴퓨터를 만든다.
클라이언트의 요청은 FactoryOfComputerFactory 공장이 받아서 ComputerFactory에게 메시지를 전달한다.
두 패턴의 차이를 그림으로 보면 아래와 같다.
즉 결정적인 차이는 각 객체(부품)를 연관성(제조사)에 따라 조합하여 반환하는 팩토리가 하나 추가되었다(하청의 하청의 하청 같은 느낌). 즉 추상 팩토리 패턴은 팩토리 메서드 패턴보다 더 캡슐화하여 연관된 로직끼리 더 세밀하게 추상화를 시킨다.
[디자인패턴] 디자인패턴이란? - 생성패턴, 구조패턴, 행위패턴