해당 포스팅은 [Design Pattern] 팩토리 (Factory) 패턴 의 하위 문서입니다.
1. 개요
추상 팩토리 디자인 패턴 (Abstract Factory Design Pattern) (이하 추상 팩토리) 은 관련된 여러 객체들의 생성(Creation)과 책임(Responsibility)을 공장(Factory) 의 하위 클래스에 위임(Delegate) 하여 하위 클래스에서 연관된 객체들을 생성하고 이들을 조합하여 사용할 수 있도록 하는 패턴이다.
추상 팩토리 여러 메소드로 이루어진 인터페이스를 제공하고 각 메소드는 서로 연관된 객체를 생성한다.
2. 상황
- 객체 생성이 복잡하거나 변경되기 쉬울 때
- 객체 생성 코드가 중복될 때
3. 다이어그램
3.1. 설명
Product1
,Product2
: 제품군에 해당하는 추상 클래스이다.Product1A
,Product1B
,Product2A
,Product2B
:Product1
,Product2
각각에 대응되는 하위 구체 클래스이다.Factory
: 추상 클래스이다.FactoryA
,FactoryB
:Factory
클래스의 하위 구현 클래스로 제품을 생성하는 역할을 수행한다.createProduct1()
,createProduct2()
: 각Factory
구체 클래스에서 구현된 메소드로, 각각의 제품군에 해당하는Product1
및Product2
객체를 생성한다.
4. 구현
abstract class Product1 {}
class Product1A extends Product1 {}
class Product1B extends Product1 {}
abstract class Product2 {}
class Product2A extends Product2 {}
class Product2B extends Product2 {}
public abstract class Factory {
public abstract Product1 createProduct1();
public abstract Product2 createProduct2();
}
class FactoryA extends Factory {
@Override
public Product1A createProduct1() { return new Product1A(); }
@Override
public Product2A createProduct2() { return new Product2A(); }
}
class FactoryB extends Factory {
@Override
public Product1B createProduct1() { return new Product1B(); }
@Override
public Product2B createProduct2() { return new Product2B(); }
}
public class Client {
public static void main(String[] args) {
Factory factoryA = new FactoryA();
Factory factoryB = new FactoryB();
Product1A product1A = factoryA.createProduct1();
Product2A product2A = factoryA.createProduct2();
Product1B product1B = factoryB.createProduct1();
Product2B product1B = factoryB.createProduct2();
}
}
5. 예시
import java.util.ArrayList;
import java.util.List;
public abstract class Calculator<T> {
public abstract T execute(T a, T b);
}
abstract class Adder<T> extends Calculator<T> {}
abstract class Subtractor<T> extends Calculator<T> {}
class NumberAdder extends Adder<Double> {
@Override
public Double execute(Double a, Double b) { return a + b; }
}
class StringAdder extends Adder<String> {
@Override
public String execute(String a, String b) { return a + b; }
}
class ListAdder<T> extends Adder<List<T>> {
@Override
public List<T> execute(List<T> a, List<T> b) {
List<T> list = new ArrayList<>(a);
list.addAll(b);
return list;
}
}
class NumberSubtractor extends Subtractor<Double> {
@Override
public Double execute(Double a, Double b) { return a - b; }
}
class StringSubtractor extends Subtractor<String> {
@Override
public String execute(String a, String b) {
String text = a;
return text.replace(b, "");
}
}
class ListSubtractor<T> extends Subtractor<List<T>> {
@Override
public List<T> execute(List<T> a, List<T> b) {
List<T> list = new ArrayList<T>(a);
list.removeAll(b);
return list;
}
}
import java.util.List;
public abstract class CalculatorFactory<T> {
public abstract Calculator<T> createAdder();
public abstract Calculator<T> createSubtractor();
}
class NumberFactory extends CalculatorFactory<Double> {
public Adder<Double> createAdder() {
return new NumberAdder();
}
public Subtractor<Double> createSubtractor() {
return new NumberSubtractor();
}
}
class StringFactory extends CalculatorFactory<String> {
public Adder<String> createAdder() {
return new StringAdder();
}
public Subtractor<String> createSubtractor() {
return new StringSubtractor();
}
}
class ListFactory<T> extends CalculatorFactory<List<T>> {
public Adder<List<T>> createAdder() {
return new ListAdder<T>();
}
public Subtractor<List<T>> createSubtractor() {
return new ListSubtractor<T>();
}
}
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class Client {
public static void main(String[] args) {
CalculatorFactory<Double> intFactory = new NumberFactory();
Calculator<Double> numberAdder = intFactory.createAdder();
Calculator<Double> numberSubtractor = intFactory.createSubtractor();
Double numberLeft = 40.0;
Double numberRight = 30.5;
Double numberAddResult = numberAdder.execute(numberLeft, numberRight);
Double numberSubtractResult = numberSubtractor.execute(numberLeft, numberRight);
System.out.println("\n[Number]");
System.out.println(numberLeft + " + " + numberRight + " = " + numberAddResult);
System.out.println(numberLeft + " - " + numberRight + " = " + numberSubtractResult);
CalculatorFactory<String> strFactory = new StringFactory();
Calculator<String> strAdder = strFactory.createAdder();
Calculator<String> strSubtractor = strFactory.createSubtractor();
String strLeft = "abcd";
String strRight = "bc";
String strAddResult = strAdder.execute(strLeft, strRight);
String strSubtractResult = strSubtractor.execute(strLeft, strRight);
System.out.println("\n[String]");
System.out.println(strLeft + " + " + strRight + " = " + strAddResult);
System.out.println(strLeft + " - " + strRight + " = " + strSubtractResult);
CalculatorFactory<List<Integer>> listFactory = new ListFactory<>();
Calculator<List<Integer>> listAdder = listFactory.createAdder();
Calculator<List<Integer>> listSubtractor = listFactory.createSubtractor();
List<Integer> listLeft = new ArrayList<>(Arrays.asList(1, 2, 3, 4));
List<Integer> listRight = new ArrayList<>(Arrays.asList(2, 3));
List<Integer> listAddResult = listAdder.execute(listLeft, listRight);
List<Integer> listSubtractResult = listSubtractor.execute(listLeft, listRight);
System.out.println("\n[List]");
System.out.println(listLeft + " + " + listRight + " = " + listAddResult);
System.out.println(listLeft + " - " + listRight + " = " + listSubtractResult);
}
}
실행결과
[Number]
40.0 + 30.5 = 70.5
40.0 - 30.5 = 9.5
[String]
abcd + bc = abcdbc
abcd - bc = ad
[List]
[1, 2, 3, 4] + [2, 3] = [1, 2, 3, 4, 2, 3]
[1, 2, 3, 4] - [2, 3] = [1, 4]
6. 장단점
6.1. 장점
- 코드 중복 최소화
- 유연성, 확장성 증가
- Client 코드 간소화
6.2. 단점
- 새로운 객체를 추가 시 하위 클래스 생성 필요
- 코드 복잡성 증가
관련 포스팅
참고자료
728x90
'Develop > Design Pattern' 카테고리의 다른 글
[Design Pattern] 데코레이터 (Decorator) 패턴 (0) | 2024.06.19 |
---|---|
[Design Pattern] 싱글톤 (Singleton) 패턴 (0) | 2023.12.25 |
[Design Pattern] 팩토리 메소드 (Factory Method) 패턴 (0) | 2023.12.20 |
[Design Pattern] 팩토리 (Factory) 패턴 (0) | 2023.12.20 |
[Design Pattern] 단순 팩토리 (Simple Factory) 패턴 (0) | 2023.12.18 |