추상 팩토리 패턴
- 구체적인 클래스의 인스턴스를 생성하는 방법을 캡슐화하여 일관된 방식으로 연관된 객체를 생성할 수 있게 지원하는 패턴
- Concrete Factory에서 Concrete Instance를 만들어주는 것까지는 팩토리 메서드 패턴과 비슷하지만
- 초점이 팩토리를 사용하는 클라이언트 쪽에 있음
- 목적 자체가 팩토리에서 인스턴스를 만드는 코드를 인터페이스 기반으로 구현할 수 있게끔 지원해 주는 패턴
- 구체적인 클래스에 의존하지 않고 객체를 생성할 수 있기 때문에 클라이언트 코드를 변경하지 않아도 됨

부연 설명
- 팩토리 메서드 패턴에서 Client만 추가되었다고 생각해도 무방
추상 팩토리 패턴 구현 예시
- 앞서 설명했다시피 추상 팩토리 메서드 패턴과 유사하지만 초점이 클라이언트에서 팩토리를 사용하는 방법에 있음
1. Factory 인터페이스 및 ConcreteFactory 정의
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
interface AbstractFactory { | |
AbstractProduct getProduct(); | |
} | |
public class ConcreteFactoryA implements AbstractFactory { | |
@Override | |
public AbstractProduct getProduct() { | |
return new ProductA(); | |
} | |
} | |
class ConcreteFactoryB implements AbstractFactory { | |
@Override | |
public AbstractProduct getProduct() { | |
return new ProductB(); | |
} | |
} |
2. Product 인터페이스 및 다양한 Product 정의
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public interface AbstractProduct { | |
void productFunc(); | |
} | |
public class ProductA implements AbstractProduct { | |
@Override | |
public void productFunc() { | |
System.out.println("ProductA"); | |
} | |
} | |
public class ProductB implements AbstractProduct { | |
@Override | |
public void productFunc() { | |
System.out.println("ProductB"); | |
} | |
} |
3. 추상 팩토리 패턴을 사용하는 클라이언트 코드 작성
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class Client { | |
private AbstractProduct product; | |
public Client(AbstractFactory factory) { | |
this.product = factory.getProduct(); | |
} | |
public static void main(String[] args) { | |
createClientAndRunProductFunc(new ConcreteFactoryA()); | |
createClientAndRunProductFunc(new ConcreteFactoryB()); | |
} | |
private static void createClientAndRunProductFunc(AbstractFactory factory) { | |
Client client = new Client(factory); | |
client.product.productFunc(); | |
} | |
} |

부연 설명
- 추상 팩토리 메서드 패턴과 달리 클라이언트 코드가 바뀌지 않음
팩토리 메서드 패턴 vs 추상 팩토리 패턴
팩토리 메서드 패턴 | 추상 팩토리 패턴 | |
공통점 | 두 패턴 모두 구체적인 객체 생성 과정을 추상화한 인터페이스를 제공 | |
관점 | 팩토리를 구현하는 방법(inheritance)에 초점을 둠 | 팩토리를 사용하는 방법(composition)에 초점을 둠 |
목적 | 구체적인 객체 생성 과정을 하위 또는 구체적인 팩토리로 옮기는 것이 목적 | 관련있는 여러 객체를 구체적인 클래스에 의존하지 않고 생성할 수 있게 해주는 것이 목적 |
실무에서 쓰이는 추상 팩토리 패턴
1. 단순한 추상 팩토리 패턴
- xml 형태의 문서를 자바 클래스로 변환해주는 DocumentBuilderFactory
- 추상적인 타입인 DocumentBuilder 기반으로 구현하게 됨으로 추상 팩토리 패턴이라 할 수 있음
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public static void main(String[] args) throws ParserConfigurationException, IOException, SAXException { | |
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); | |
DocumentBuilder builder = factory.newDocumentBuilder(); // 추상적인 타입인 DocumentBuilder 기반으로 구현하게 됨으로 추상 팩토리 패턴이라 할 수 있음 | |
Document document = builder.parse(new File("src/main/resources/config.xml")); | |
System.out.println(document.getDocumentElement()); | |
} |
2. 스프링에서 제공하는 FactoryBean 인터페이스
- Bean Object를 만들 때 만드는 과정이 단순히 생성자를 통해 만들 수 없고 좀 복잡할 경우 FactoryBean의 구현체를 만들어서 빈으로 등록
- FactoryBean에서 만들어주는 Object가 빈으로 등록 (getObject 참고)
2.1 config.xml
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="UTF-8"?> | |
<beans xmlns="http://www.springframework.org/schema/beans" | |
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> | |
<bean id="hello" class="java.lang.String"> | |
<constructor-arg value="hello"/> | |
</bean> | |
<bean id="hexagonal" class="com.tistory.jaimemin.designpattern.abstract_factory.java.TemplateFactory"/> | |
</beans> |
2.2 FactoryBean 구현체 및 FactoryBean 사용하는 클라이언트 코드
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@Component | |
public class TemplateFactory implements FactoryBean<Template> { | |
@Override | |
public Template getObject() throws Exception { | |
Template template = new HexagonalTemplate(); | |
template.setName("hexagonal"); | |
return template; | |
} | |
@Override | |
public Class<?> getObjectType() { | |
return Template.class; | |
} | |
} | |
public static void main(String[] args) { | |
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("config.xml"); | |
Template hexagonalTemplate = applicationContext.getBean("hexagonal", Template.class); | |
System.out.println(hexgonalTemplate.getName()); | |
} |
부연 설명
- 프레임워크를 만드는 쪽에 보통 추상 팩토리 메서드 패턴 혹은 추상 팩토리 패턴이 많이 적용되어 있음
- 스프링 프레임워크 내부 코드는 바뀌지 않으면서 확장 가능하기 때문에 OCP 원칙을 따랐다고 할 수 있음
참고
코딩으로 학습하는 GoF의 디자인 패턴 - 백기선 강사님
반응형
'Design Pattern' 카테고리의 다른 글
[디자인 패턴] 프로토타입 패턴 (Prototype Pattern) (0) | 2024.06.22 |
---|---|
[디자인 패턴] 빌더 패턴 (Builder Pattern) (0) | 2024.06.21 |
[디자인 패턴] 팩토리 메서드 패턴 (Factory Method Pattern) (0) | 2024.06.18 |
[디자인 패턴] 싱글톤 패턴 (Singleton Pattern) (0) | 2024.06.13 |
[디자인 패턴] JDK 동적 프록시와 CGLIB (0) | 2021.12.11 |