-
디자인 패턴 스터디 기록 (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 정리
팩토리 메소드 패턴 - 클래스의 객체를 서브 클래스에서 결정
추상 팩토리 패턴 - 의존성을 해결하기 위해 객체로 이루어진 제품군을 생성하는 인터페이스를 제공하고 구상 클래스를 서브 클래스에서 만드는 것
'✏️ 스터디 모음집 > 디자인 패턴 스터디' 카테고리의 다른 글
클린코드 - 깨끗한 테스트 코드 짜기 (0) 2022.11.05 디자인 패턴 스터디 기록 (6) - 싱글톤 패턴 (0) 2022.11.02 디자인 패턴 스터디 기록 (4) - 데코레이터 패턴 (0) 2022.11.02 디자인 패턴 스터디 기록 (3) - 객체 간의 강한 결합 VS 느슨한 결합 (0) 2022.10.27 디자인 패턴 스터디 기록 (2) - 옵저버 패턴 (0) 2022.10.27