추상 팩토리 패턴(Abstract Factory Pattern)
- 추상 팩토리 패턴은 생성패턴(Creational Pattern) 중 하나이다.
- 생성 패턴은 인스턴스를 만드는 절차를 추상화하는 패턴이다.
- 생성 패턴에 속하는 패턴들은 객체를 생성, 합성하는 방법이나 객체의 표현방법을 시스템과 분리해준다.
- 생성 패턴을 이용하면 무엇이 생성되고, 누가 이것을 생성하며, 이것이 어떻게 생성되는지, 언제 생성할 것인지 결정하는 데 유연성을 화 보할 수 있습니다.
장점
- 추상 팩토리 패턴은 클라이언트 코드로부터 서브 클래스의 인스턴스화를 제거하여 서로 간의 종속성을 낮추고, 결합도를 느슨하게 하며(Loosely Coupled), 확장을 쉽게 한다.
- 추상 팩토리 패턴은 클라이언트와 구현 객체들 사이에 추상화를 제공한다.
- 추상 팩토리 패턴에서는 팩토리 클래스에서 서브 클래스를 생성하는 데에 있어서 필요한 if-else, switch 문을 걷어냅니다.
팩토리 메소드 패턴 vs 추상 팩토리 패턴
- 둘 다 구체적인 객체 생성 과정을 추상화한 인터페이스를 제공한다.
팩토리 메소드 패턴 |
추상 팩토리 패턴 |
|
관점 | "팩토리를 구현하는 방법"에 초점 | "팩토리를 사용하는 방법"에 초점 |
목적 | 구체적인 객체 생성 과정을 하위 또는 구체적인 클래스로 옮기는 것이 목적 | 관련있는 여러 객체를 구체적인 클래스에 의존하지 않고 만들 수 있게 해주는 것이 목적 |
코드
* 부동산 중개 수수료 계산 프로그램 가정(매매/임대차)
- 중개 정책 interface 생성 :
interface를 구현하는 하위 클래스에서 수수료 계산 로직을 구현한다.
java8 이후로 default 메소드를 사용하면 interface 내부에서 로직 작성이 가능하다. (default 명시)
public interface BrokeragePolicy {
BrokerageRule createBrokerageRule(Long price);
default Long calculate(Long price) {
BrokerageRule rule = createBrokerageRule(price);
return rule.calcMaxBrokerage(price);
}
}
- 매매 중개 수수료 class :
java7 이후부터 _는 숫자 리너털 어디에도 사용할 수 있다. 가독성 향상
public class PurchaseBrokeragePolicy implements BrokeragePolicy{
public BrokerageRule createBrokerageRule(Long price) {
BrokerageRule rule;
if(price < 50_000_000) {
rule = new BrokerageRule(0.6, 250_000L);
} else if(price < 200_000_000) {
rule = new BrokerageRule(0.5, 800_000L);
}else if(price < 600_000_000) {
rule = new BrokerageRule(0.4, null);
}else if(price < 900_000_000) {
rule = new BrokerageRule(0.5, null);
}else{
rule = new BrokerageRule(0.9, null);
}
return rule;
}
}
- 임대차 중개 수수료 class
public class RentBrokeragePolicy implements BrokeragePolicy{
public BrokerageRule createBrokerageRule(Long price) {
BrokerageRule rule;
if(price < 50_000_000) {
rule = new BrokerageRule(0.5, 200_000L);
} else if(price < 100_000_000) {
rule = new BrokerageRule(0.4, 300_000L);
}else if(price < 300_000_000) {
rule = new BrokerageRule(0.3, null);
}else if(price < 600_000_000) {
rule = new BrokerageRule(0.4, null);
}else{
rule = new BrokerageRule(0.8, null);
}
return rule;
}
}
- 추상 팩토리 Interface Class :
추상 팩토리 역할을 하는 인터페이스 생성
public interface BrokeragePolicyAbstractFactory {
public BrokeragePolicy createBrokerageRule();
}
- 팩토리 Interface를 구현하는 클래스(매매 중개 수수료) :
작성한 팩토리 인터페이스의 createBrokerageRule() 메소드의 리턴 타입이 super class인 BrokeragePolicy이다.
이는 자바의 다형성을 잘 활용한 방식이다.
public class PurchaseBrokerageFactory implements BrokeragePolicyAbstractFactory{
@Override
public BrokeragePolicy createBrokerageRule() {
return new PurchaseBrokeragePolicy();
}
}
- 팩토리 Interface를 구현하는 클래스(임대차 중개 수수료)
public class RentBrokerageFactory implements BrokeragePolicyAbstractFactory{
@Override
public BrokeragePolicy createBrokerageRule() {
return new RentBrokeragePolicy();
}
}
- 서브 클래스들을 생성하기 위해서 if-else 없이 분개 처리해주는 클래스
public class BrokeragePolicyFactory {
public static BrokeragePolicy getBrokeragePolicy(BrokeragePolicyAbstractFactory policyAbstractFactory) {
return policyAbstractFactory.createBrokerageRule();
}
}
- 중개 수수료 계산 api
// 매매 중계수수료 계산 메소드
@GetMapping("/api/calc/brokeragepur")
public Long calcBrokeragePurchase(@RequestParam ActionType actionType,
@RequestParam Long price) {
BrokeragePolicy policy = BrokeragePolicyFactory.getBrokeragePolicy(new PurchaseBrokerageFactory());
return policy.calculate(price);
}
// 임대차 중계수수료 계산 메소드
@GetMapping("/api/calc/brokeragerent")
public Long calcBrokerageRent(@RequestParam ActionType actionType,
@RequestParam Long price) {
BrokeragePolicy policy = BrokeragePolicyFactory.getBrokeragePolicy(new RentBrokerageFactory());
return policy.calculate(price);
}
실무 사용 사례
Spring에서 FactoryBean과 그 구현체
정리
- 객체 생성을 담당 및 처리하는 팩토리 클래스를 생성하여서 객체 생성에 관한 확장도 쉽게 구성할 수 있다.
팩토리 패턴과 다르게 분개 처리하는 부분이 사라진다.
'JAVA > Design Pettern' 카테고리의 다른 글
[Design Pattern] 템플릿 메서드 패턴 (0) | 2022.03.23 |
---|---|
[Design Pattern] 프록시 패턴 (0) | 2022.03.22 |
[Design Pattern] 어댑터 패턴 (0) | 2022.03.16 |
[Design Pattern] 싱글톤 패턴 (0) | 2022.03.15 |
[Design Pattern] 빌더 패턴 (0) | 2022.03.14 |