3. 추상 팩토리(Abstract factory) 패턴
😉 : ‘코딩으로 학습하는 GoF의 디자인 패턴’ 공부 기록입니다.
추상 팩토리 패턴이란?
적용 예시
AS-IS
해당 부분은 이전 글인 팩토리 메소드 패턴의 코드를 기반으로 하기 때문에 해당 글을 먼저 읽는 것을 추천합니다.
public class Book {
private String type;
private String color;
private int pages;
private Author author;
private Publisher publisher;
}
public class NovelBookFactory implements BookFactory{
@Override
public Book createBook() {
Book book = new NovelBook();
book.setAuthor(new Author());
book.setPublisher(new Publisher());
return book;
}
}
팩토리 메소드 패턴의 TO-BE의 Book에 작가(Author)와 출판사(Publisher)가 추가된 상황이라고 하자. 만약에 NovelBookFactory에서 책의 작가나 출판사를 이 상태에서 변경하려면 NovelBookFactory 코드에 직접적인 수정이 필요하다.
TO-BE
public interface BookPartsFactory{
Author createAuthor();
Publisher createPublisher();
}
public class NovelBookPartsFactory implements BookPartsFactory{
@Override
public Author createAuthor(){
return new NovelAuthor(); // interface Author의 구현체
}
@Override
public Publisher createPublisher(){
return new NovelPublisher(); // interface Publisher의 구현체
}
}
public class NovelBookFactory implements BookFactory{
private BookPartsFactory bookPartsFactory;
public NovelBookFactory(BookPartsFactory bookPartsFactory){
this.bookPartsFactory = bookPartsFactory
}
@Override
public Book createBook() {
Book book = new NovelBook();
book.setAuthor(bookPartsFactory.createAuthor());
book.setPublisher(bookPartsFactory.creaetPublisher());
return book;
}
}
하지만 위와 같이 factory interface를 사용한다면, NovelBookFactory 생성 시 외부에서 주입하는 BookPartsFactory만 필요에 맞게 수정하면 책의 구성요소를 바꿀 수 있다.
public class Example{
public static void main(String[] args){
BookFactory bookFactory = new NovelBookFactory(new NovelBookPartsFactory());
Book book = bookFactory.createBook();
}
}
이를 통해 추상 팩토리 패턴은 개방 폐쇄 원칙 (Open Closed Principal)을 지킬 수 있게 하는 디자인 패턴임을 알 수 있다.
팩토리 메소드 패턴 vs 추상 팩토리 패턴
둘 다 객체 생성 과정을 추상화한 인터페이스를 제공한다. 하지만 어느 관점이냐에 따라 달라진다고 할 수 있다. 팩토리 메소드 패턴은 객체를 만드는 과정, 구현하는 방법(inheritance)에 더 집중되어있다고 보면 된다. 인스턴스를 만드는 과정을 팩토리로 숨기고, 팩토리를 제공한다. 즉, 구체적인 객체 생성 과정을 하위 또는 구체적인 클래스로 옮긴다. 거의 비슷하지만, 보는 관점을 팩토리를 사용하는 방법(composition)에 초점을 두고 보는게 추상 팩토리 패턴이다. 팩토리를 통해서 추상화된 인터페이스만 클라이언트가 쓸 수 있게 해서 구체적인 클래스에 의존하지 않고 여러 객체를 만들 수 있게 한다.
공부하다가 생각난 점
스프링을 사용해 본 사람이라면 이걸 보자마자 바로 Bean 개념이 생각날 것 같다. 빈으로 등록하면 해당 빈을 다른 곳에 주입해서 사용할 수 있는데, 특정 인터페이스 구현체를 각각 빈으로 등록한 다음, 필요에 따라 주입해서 사용하는 부분이 추상 팩토리 패턴과 관련된 것 같다. (사실 강의 들을 때 생각했는데, 강의 마지막 부분에 나오는 내용이더라)