본문 바로가기
SWE/C++ OOP

[디자인 패턴] Abstract Factory Pattern 추상 팩토리 패턴

by S나라라2 2021. 7. 22.
반응형

 

 

추상팩토리패턴을 공부하기 전에 '심플 팩토리'와 '팩토리 메소드 패턴'을 먼저 공부하면, 이해가 수월할 것이다.

https://flower0.tistory.com/414

 

[디자인 패턴] Simple Factory 심플팩토리

팩토리 패턴에는 다음과 같이 두 가지 패턴이 있다. - 팩토리 메소드 패턴 Factory method Pattern - 추상 팩토리 패턴Abstract Factory Pattern 이 두 가지 패턴을 공부하기위해, 두 패턴의 베이스인 'Simple Fac..

flower0.tistory.com

팩토리 메소드 패턴

https://flower0.tistory.com/415

 

[디자인 패턴] Factory Method Pattern 팩토리 메소드 패턴

팩토리 메소드 패턴의 기조인 '심플 팩토리'는 아래 링크에 정리해두었다. https://flower0.tistory.com/414 [디자인 패턴] Simple Factory 심플팩토리 팩토리 패턴에는 다음과 같이 두 가지 패턴이 있다. - 팩

flower0.tistory.com

 

추상 팩토리 패턴 Abstract Factory Pattern

 

[개념] 추상 팩토리 패턴이란?

추상 팩토리 패턴은 서로 연관되거나 의존적인 객체들의 조합(family)을 만드는 인터페이스를 제공하는 방법이다.

 

[예시]

피자 만드는 것을 (또ㅜ.ㅜ) 예로 들어보자. 

팩토리 메소드 패턴까지 설명하자면, PizzaStore가 있고 그걸 상속받는 서브 클래스 (NYPizzaStore, ChicagoPizzaStore)가 있다.

 

여기서 뉴욕가게와 시카고가게에서 Pizza(객체)를 만들 때 사용되는 재료들은 중복된다.

세부 디테일이 다를 수 있지만 두 가게 모두 도우, 소스, 토핑, 치즈가 필요하다.

이러한 부분을 묶어서 팩토리화하는 것이 추상팩토리패턴이다. 

 

즉 팩토리를 이용하여 피자에서 쓰이는 재료를 만드는 것이다. 만들어지는 구체적인 재료들은 어떤 팩토리를 쓰는지에 따라 달리질 것이다. 도우라고 하더라도 두꺼운 도우일지, 씬일지는 팩토리에 의해 결정된다는 말이다.

 

 

NYPizzaIngredientFactory의 createThough()를 호출할 경우, 씬 도우를 반환할 것이고,

ChicagoPizzaIngreidentFactory의 createThough()를 호출할 경우, 두꺼운 도우를 반환할 것이다. 

 

피자를 사용하는 client 입장(PizzaStore)에서는 반환하는 도우의 디테일은 알 필요가 없다. 단지 도우라는 재료(수퍼클래스의 Dough)로만 알고 있으면 되는 것이다. 

 

-> 만들어지는 재료들은 어떤 팩토리를 쓰는지에 따라 달라질 것이고, 피자 클래스에서는 전혀 신경쓸 필요가 없다.

이렇게 함으로써 서로 다른 상황별로 적당한 제품을 생산할 수 있는 다양한 팩토리를 구현할 수 있다. 

 

public interface PizzaIngredientFactory {
	public Dough createDough();
    public Sauce createSauce();
    public Cheese createCheese();
    public Pepperoni createPepperoni();
}

PizzaIngredientFactory 인터페이스에 각 재료별 생성 메소드를 정의한다.

public class NYPizzaIngredientFactory implements PizzaIngredientFactory {
	public Dough createDough() {
    	return new ThinCrustDough();
    }
    public Sauce createSauce() {
    	return new MarinaraSauce();
    }
    public Cheese createCheese() {
    	return new ReggianoCheese();
    }
    public Pepperoni createPepperoni() {
    	return new SlicePepperoni();
    }
    public Clams createClam() {
    	return new FreshClams();
    }
}

 

client단 구현 - 피자 가게

public class NYPizzaStore extends PizzaStore {
	protected Pizza createPizza(String item) {
    	Pizza pizza = null;
        PizzaIngredientFactory ingredientFactory = new NYPizzaIngredientFactory();
    	// 뉴욕 피자 가게에는 뉴욕 피자 원재료 공장을 전달해줘야 한다. 
        // 뉴욕풍 피자를 만들기 위한 재료는 이 공장에서 공급된다.
        
        if( item.equals("cheese") ) {
        	pizza = new CheesePizza(ingredientFactory);
            // 피자 재료를 위해 쓸 팩토리를 각 피자 객체에 전달해준다.
            pizza.setName("New York Style Cheese Pizza");
        } else if( item.equals("clam") ) {
        	pizza = new ClamPizza(ingredientFactory);
            pizza.setName("New York Style Clam Pizza");
        } else if( item.equals("pepperoni") ) {
        	pizza = new PepperoniPizza(ingredientFactory);
            pizza.setName("New York Style Pepperoni Pizza");
        }
        // 각 형식의 피자마다 새로운 Pizza인스턴스를 만들고 원재료를 공급 받는데 필요한 팩토리를 지정해정해준다.
        return pizza;
    }
}

Pizza 클래스 - PizzaIngredientFactory가 필요하다.

public class CheesePizza extends Pizza {
	PizzaIngredientFactory ingredientFactory;
    
    // 각 피자 클래스에서는 생성자를 통해서 팩토리를 전달 받는다.
    // 이 팩토리는 인스턴스 변수에 저장한다.
    public CheesePizza(PizzaIngredientFactory ingredientFactory) {
    	this.ingredientFactory = ingredientFactory;
    }
    
    voide prepare() {
    	System.out.println("Preparing " + name);
        doug = ingredientFactory.createDough();
        sauce = ingredientFactory.createSauce();
        cheese = ingredientFactory.createCheese();
    	// 재료가 필요할 때마다 팩토리에 있는 메소드를 호출해서 만들어 온다.
    }
}

 

[장점]추상 팩토리의 장점

구상 클래스에 직접 의존하지 않고서로 관련된 객체들로 이루어진 제품군을 만들 수 있다.

구상 형식에 대한 의존을 피하고 추상화를 지향할 수 있다.

 

[단점] 추상 팩토리의 단점

제품군에 제품을 추가하려면 인터페이스를 바꿔야 한다. 

위의 피자 예시로 보면, NYPizzaStore에 불고기피자를 추가하려면 PizzaIngredientFactory를 수정해야 하고, 그것을 상속받은 모든 서브 클래스(NYPizzaIngredientFactory)의 인터페이스도 수정이 필요하다. 

일이 매우 커진다.

 

 

[공통점] 심플 팩토리, 팩토리 메소드 패턴, 추상 팩토리 패턴의 공통점

결국 모든 팩토리의 공통점은 객체 생성을 캡슐화해서 애플리케이션의 결합을 느슨하게 만들고, 특정 구현에 덜 의존이게 만든다는 것이다.

키워드: 캡슐화, 의존성 줄임, 인터페이스화

 

반응형