ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 디자인 패턴 (5) - 추상 팩토리 패턴
    언어/디자인패턴 2023. 9. 11. 14:09

    1. 추상 팩토리 패턴이란?

     

    - 연관성 있는 객체 군이 여러개 있을 경우 이를 묶어 추상화

    - 구체적 상황이 주어지면, 팩토리 객체를 통해 객체 군을 구현화 하는 생성 패턴이다.

    - 핵심은 제품군 집합을 타입별로 찍어낼 수 있다는 점이다.

     

    1.1 추상 팩토리 패턴 구조 

    출차: https://inpa.tistory.com/entry/GOF-%F0%9F%92%A0-%EC%B6%94%EC%83%81-%ED%8C%A9%ED%86%A0%EB%A6%ACAbstract-Factory-%ED%8C%A8%ED%84%B4-%EC%A0%9C%EB%8C%80%EB%A1%9C-%EB%B0%B0%EC%9B%8C%EB%B3%B4%EC%9E%90

    1. AbstractFactory: 최상위 공장 클래스 -> 여러 제품군을 생성하는 여러 메서드를 포함

    2. ConcreteFactory: 서브 공장 클래스들은 타입에 맞는 제품 객체 반환하도록 메소드 오버라이딩

    3. AbstractProduct: 각 제품군을 추상화 (대분류)한 인터페이스

    4. ConcreteProduct : 각 타입 제품의 구현체 -> 팩토리를 통해 생성됨

    5. Client : 추상화된 인터페이스만으로 제품을 받으므로, 구체적인 타입은 모른다.

     

    1.2 Abstract Factory VS Factory Method

     

    - 둘다 구체적인 타입은 감추고 객체를 생성하는 패턴 유사

    - 팩토리 메서드 패턴은 객체 생성 이후 해야할 일의 공통점 정의 초점

    - 추상 팩토리 패턴은 객체 집합 군의 공통점에 초점

     

    * 팩토리 메서드 패턴은 구체적인 생성과정을 클래스로 옮기는 것이 목적 (여러 팩토리가 하나의 카테고리 생성)

       추상 팩토리 메서드 패턴은 팩토리가 여러 제품군 생성을 지원 

    * 팩토리 패턴은 주로 상속을 통해 추상 팩토리 메서드 패턴은 주로 구성을 통해 만든다 (의존관계)

     

    1.3 예시 

     

    - 제품군 정의 (추상화하여 구현체 분리)

    interface AbstractProductA{
    	//카테고리 (버섯)
    }
    class ConcreteProductA1 implements AbstractProductA{
    	//구현체 (카테고리 별 실제 제품) (느타리버섯)
    }
    class ConcreteProductA2 implements AbstractProductA{
    	//(팽이버섯)
    }
    
    interface AbstractProductB{
    	//카테고리 (나무)
    }
    
    class ConcreteProductB1 implements AbstractProductB{
    	//(고목나무)
    }
    class ConcreteProductB2 implements AbstractProductB{
    	//(미루나무)
    }

    - 공장클래스 

    interface AbstractFactory{
    
    	AbstractProductA createProductA(); //버섯 중 하나 생성
        AbstractProductB createProductB();// 나무 중 하나 생성
       
    }
    
    class ConcreteFactory1 implements AbstractFactory{ //느타리 미루 공장
    	public AbstractProductA createProductA(){ //버섯 중 하나 리턴
        	return new ConcreteProductA1(); // 느타리
        }
        public AbstractProductB createProductB(){ //나무 중 하나 리턴
        	return new ConcreteProductB2();//미루나무 
        }
        
        class ConcreteFactory2 implements AbstractFactory{ // 팽이 고목 공장
    	public AbstractProductA createProductA(){ //버섯 중 하나 리턴
        	return new ConcreteProductA2(); // 팽이
        }
        public AbstractProductB createProductB(){ //나무 중 하나 리턴
        	return new ConcreteProductB1();//고목나무 
        }
    
    }

     

    1.5 추상 팩토리 패턴 특징

     

    - 사용 시기: 관련 제품의 다양한 제품군과 함께 동작시 

                        여러 제품군 중 하나 선택해서 시스템 설정해야할 때 (한번에 구성한 제품이 달라야함)

                        제품에 대한 라이브러리 제공하고, 구현이 아닌 인터페이스 노출

     

    - 장점: 결합도 낮춤, 제품 군 교체가 쉽다,SRP,OCP준수 

    - 단점: 클래스 너무 많아짐, 새로운 제품 대분류 생성이 어렵다 (많이 고쳐야함), 세부사항이 변경되면 모든 팩토리 수정이 필요 

     

    *초기설정 + 설정 하는 클래스 다양성이 일정할 때 쓰자 

     

    2. 피자 원재료 팩토리 만들기 

     

    - 지점별로 원재료가 달라짐 

     

    public interface PizzaIngredientFactory{
    
    
    	public Dough createDough(); // 대분류
        public Sauce createSauce();
        //.. 각 재료별 팩토리용 인터페이스
    
    }
    public class NYPizzaIngredientFactory implements PizzaIngredientFactory{
    
    public Dough createDough(){
    	return new ThinCrustDough(); //구체 타입 리턴
    }
        public Sauce createSauce(){
        return new MarinarSauce();
        }
        
        //여러 재료들 한번에 설정 
    }

    - Pizza 객체 

    public abstract class Pizza{
    
    	String name;
        Dough dough;
        //..피자재료
        
        abstract void prepare(); // 피자만들 때 필요한 재료들을 원재료 팩토리에서 가져올 것
    							//기존 코드와 달라진점 -> 피자원재료 팩토리 추가해서 한번에 재료 설정할 것 
    }
    
    
    public class CheesePizza extends Pizza{
    
    	PizzaIngredientFactory ingredientFactory; //재료군에서 구체 재료를 생성할 팩토리 
        
        public CheesePizza(PizzaIngridientFactory i){
        	this.ingredientFactory = i;
        }
        void prepare(){
        	i.createDough();//등
        }
    }

    - Pizza Store

    public class NYPizzaStore extends PizzaStore{
    
    
    	protected Pizza createPizza(String item){
        	Pizza pi = null;
            PizzaIngredientFactory in = new NYCPizzaIngredientFactory(); //구현체 전달
            
            if(item.equals("chees")){
            	pizza = new CheesePizza(ingredientFactory); //피자 원재료 팩토리 전달
            }
            //if문 돌면서 pizza찾기 
        
        }
    }
    
    // 피자 팩토리가 생성과 동시에 원재료 팩토리도 지정

     

     

    참고자료: 

     

    헤드 퍼스트 디자인 패턴 (한빛미디어)

     

    https://inpa.tistory.com/entry/GOF-%F0%9F%92%A0-%EC%B6%94%EC%83%81-%ED%8C%A9%ED%86%A0%EB%A6%ACAbstract-Factory-%ED%8C%A8%ED%84%B4-%EC%A0%9C%EB%8C%80%EB%A1%9C-%EB%B0%B0%EC%9B%8C%EB%B3%B4%EC%9E%90

     

    💠 추상 팩토리(Abstract Factory) 패턴 - 완벽 마스터하기

    Abstract Factory Pattern 추상 팩토리 패턴은 연관성이 있는 객체 군이 여러개 있을 경우 이들을 묶어 추상화하고, 어떤 구체적인 상황이 주어지면 팩토리 객체에서 집합으로 묶은 객체 군을 구현화

    inpa.tistory.com

     

     

Designed by Tistory.