ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 디자인 패턴 스터디 기록 (5) - 팩토리 패턴, 의존성 역전
    ✏️ 스터디 모음집/디자인 패턴 스터디 2022. 11. 2.

    4. 객체지향 팩토리 패턴

    이번장에서는 최대한 느슨한 결합으로 객체지향 디자인을 하는게 목표인 장입니다.

    4-1. Simple Factory

    예제 1)

    Pizza orderPizza() {
    	Pizza pizza = new Pizza();
    
    	/* 이부분 */
    	*if(type.equals("cheese")) {
    		pizza = new CheesePizza();
    	} else if (type.equals("greek")) {
    		pizza = new GreekPizza();
    	} else if (type.equals("pepperoni")) {
    		pizza = new PepperoniPizza();
    	}* 
    
    	pizza.prepare();
    	pizza.bake();
    	pizza.cut();
    	pizza.box();
    	return pizza;
    }
    

    3가지인 피자라면 괜찮지만 여기서 몇가지의 피자가 더생긴다면 ?

    계속해서 새로운 new 여러가지피자() 를 할 것인가

    → 팩토리를 만들자!

    public class SimplePizzaFactory {
        public Pizza createPizza(String type) {
            Pizza pizza = null;
    
            if(type.equals("cheese")) {
                pizza = new CheesePizza();
            } else if (type.equals("greek")) {
                pizza = new GreekPizza();
            } else if (type.equals("pepperoni")) {
                pizza = new PepperoniPizza();
            }
    
            return pizza;
        }
    }
    
    public class PizzaStore {
        SimplePizzaFactory factory;
    
        public PizzaStore(SimplePizzaFactory factory) {
            this.factory = factory;
        }
    
        public Pizza orderPizza(String type) {
            Pizza pizza;
    
            pizza.prepare();
            pizza.bake();
            pizza.cut();
            pizza.box();
            return pizza;
        }
    }
    

    4-2. 다양한 Factory

    피자가게에서 체인점을 냈는데 지점마다 자기들만의 피자를 내고싶다

    → 지점마다 팩토리를 만들어서 해당 피자들을 찍어내면 된다!

    예제1)

    NYPizzaFactory nyFactory = new NYPizzaFactory();
    PizzaStore nyStore = new PizzaStore(nyFactory);
    nyStore.orderPizza("Veggle");
    
    ChicagoPizzaFactory chicagoFactory = new ChicagoPizzaFactory();
    PizzaStore chicagoStore = new PizzaStore(chicagoFactory);
    chicagoStore.orderPizza("Veggie");
    

    이렇게 했더니 여러 문제가 생겼음

    → 굽는방식이 여러가지가 생김 즉 팩토리마다 방식이 여러가지로 생겨서 관리가 용이하지 않음

    → 추상메소드를 만들어서 상속받아서 지점마다 해결하자가 이책에서 나온 해결 방법

    public abstract class PizzaStore {
    		// 추상 클래스
        public Pizza orderPizza(String type) {
            Pizza pizza;
            
            pizza = createPizza(type);
    
            pizza.prepare();
            pizza.bake();
            pizza.cut();
            pizza.box();
    
            return pizza;
        }
    
        abstract Pizza createPizza(String type);
    		// 추상 메소드
    }
    
    public class NYPizzaStore extends PizzaStore {
        Pizza createPizza(String item) {
    				// 추상 메소드를 상속 받아 작성
            if(type.equals("cheese")) {
                pizza = new NYStyleCheesePizza();
            } else if (type.equals("veggie")) {
                pizza = new NYStyleVeggiePizza();
            } else if (type.equals("pepperoni")) {
                pizza = new NYStylePepperoniPizza();
            }
        }
    }
    
    +@ // ChicagoPizzaStore extends PizzaStore
    
    public class PizzaTestDrive {
        public static void main(STring[] args) {
            PizzaStore nyStore = new NYPizzaStore();
            PizzaStore chicagoStore = new ChicagoPizzaStore();
    
            Pizza pizza = nyStore.orderPizza("cheese");
    				        
    
            pizza = chicagoStore.orderPizza("cheese");
        }
    
    }
    

    4-3 팩토리 메소드 패턴의 정의

    팩토리 메소드 패턴에서는 객체를 생성할 때 필요한 인터페이스를 만들고
    **어떤 클래스의 객체를 만들지는 서브클래스에 결정한다.**
    즉 클래스 객체를 만드는 일을 서브클래스에서 주도적으로 행하는 패턴을 말함
    

    4-4 객체 의존성 문제

    이러면 제일 상위에 있는 팩토리 클래스가 엄청나게 의존성이 발생되는데 이에 따른 해결법으로 의존성 뒤집기를 이용한 추상 팩토리 패턴을 제안합니다.

    헤드퍼스트책에서 지향 하는 의존성 뒤집기 원칙

    • new 를 사용하지 않고 Factory를 만들어서 변수에 저장하는 일을 방지
    • 추상 클래스 사용
    • 베이스 클래스에서 이미 구현되어 있는 메소드를 override 하지 않고 추상 메소드를 override 하자

    4-5 추상 팩토리 패턴

    public interface PizzaIngredientFactory {
        public Dough createDough();
        public Sauce createSauce();
        public Cheese createCheese();
        public Veggies[] createVeggies();
        public Pepperoni createPepperoni();
        public Calms createClam();
    }
    
    public Class NYPizzaIngredientFactory implements PizzaIngredientFactory {
    
        public Dough createDough() {}
        public Sauce createSacue() {}
        public Cheese createCheese() {}
        public Veggis[] createVeggies() {}
        public Pepperoni createPepperoni() {}
        public Clams createClam() {}
    }
    
    public class CheesePizza extends Pizza {
        PizzaIngredientFactory ingredientFactory;
    
        public CheesePizza(PizzaIngredientFactory ingredientFactory) {
            this.ingredientFactory = ingredientFactory;
        }
    
        void prepare() {
            dough = ingredientFactory.createDough();
            sauce = ingredientFactory.createSauce();
            cheese = ingredientFactory.createCheese();
        }
    
    }
    

    4-6 정리

    팩토리 메소드 패턴 - 클래스의 객체를 서브 클래스에서 결정

    추상 팩토리 패턴 - 의존성을 해결하기 위해 객체로 이루어진 제품군을 생성하는 인터페이스를 제공하고 구상 클래스를 서브 클래스에서 만드는 것

    댓글

GitHub: https://github.com/Yesung-Han