일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- Git commit 합치기
- 디자인패턴
- formik react-query submitting not working
- 리액트구글애널리틱스
- awss3
- 시스템설계
- react-ga
- 시스템설계면접예시
- s3이미지다운로드됨
- 시스템설계방법
- 가상면접3장
- 리팩토링2판4장
- 전략패턴
- 헤드퍼스트전략패턴
- 가상면접2장
- 시스템설계면접팁
- gitsquash
- git commit merge
- git commit 협업
- FirebaseAnalytics
- react
- file not found Error
- 리팩터링2판테스트
- 가상면접으로대규모시스템
- formik submitting not working
- cypress React
- 시스템설계면접
- cypressBDD
- 테스트코드책
- git squash
- Today
- Total
mingg IT
[디자인 패턴] 헤드퍼스트 디자인 패턴 4장 리뷰 본문
4장 팩토리 메소드 패턴
디자인 원칙
추상화된 것에 의존하게 만들고 구상 클래스에 의존하지 않게 만든다.
팩토리 메소드 패턴
객체를 생성할 때 필요한 인터페이스를 만든다.
어떤 클래스의 인스턴스를 만들지는 서브클래스에서 결정한다.
팩토리 메소드 패턴을 사용하면 클래스 인스턴스 만드는 일을 서브클래스에게 맡기게 된다.
팩토리 메소드 패턴 이해하기
팩토리 메소드 패턴에서는 어떤 클래스의 인스턴스를 만들지는 서브클래스에서 결정한다.
추상 팩토리 패턴
구상 클래스에 의존하지 않고도 서로 연관되거나 의존적인 객체로 이루어진 제품군을 생산하는 인터페이스를 제공함
구상 클래스는 서브클래스에서 만듬.
PizzaStore.java
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);
}
NYPizzaStore.java
public class NYPizzaStore extends PizzaStore {
Pizza createPizza(String item) {
if (item.equals("cheese")) {
return new NYStyleCheesePizza();
} else if (item.equals("veggie")) {
// return new NYStyleVeggiePizza();
} else if (item.equals("clam")) {
// return new NYStyleClamPizza();
} else if (item.equals("pepperoni")) {
// return new NYStylePeperoniPizza();
} else return null;
return null;
}
}
Pizza.java
public abstract class Pizza {
String name;
String dough;
String sauce;
List<String> toppings = new ArrayList<String>();
void prepare() {
System.out.println("준비 중" + name);
System.out.println("도우를 돌리는 중...");
System.out.println("소스를 뿌리는 중...");
System.out.println("토핑을 올리는 중");
for (String topping : toppings) {
System.out.println(" " + topping);
}
}
void bake() {
System.out.println("175도에서 25분간 굽기");
}
void cut() {
System.out.println("피자를 사선으로 자르기");
}
void box() {
System.out.println("상자에 피자 담기");
}
public String getName() {
return name;
}
}
NYStyleCheesePizza.java
public class NYStyleCheesePizza extends Pizza {
public NYStyleCheesePizza() {
name = "뉴욕 스타일 소스와 치즈 피자";
dough = "씬 크러스트 도우";
sauce = "마리나라 소스";
toppings.add("잘게 썬 레지아노 치즈");
}
}
public class PizzaTestDrive {
public static void main(String[] args) {
PizzaStore nyStore = new NYPizzaStore();
PizzaStore chicagoStore = new ChicagoPizzaStore();
Pizza pizza = nyStore.orderPizza("cheese");
System.out.println("에단이 주문한 " + pizza.getName());
pizza = chicagoStore.orderPizza("cheese");
System.out.println("조엘이 주문한 " + pizza.getName());
}
}
의존성 뒤집기
변수에 구상 클래스의 레퍼런스를 저장하지 말자
구상 클래스에서 유도된 클래스를 만들지 말자
베이스 클래스에 이미 구현되어 있는 메소드를 오버라이드 하지 말자
PizzaStore(고수준)가 Pizza(저수준)에 의존하고 있다.
원자료 팩토리 만들기
추상 팩토리 사용
PizzaIngredientFactory.java
public interface PizzaIngredientFactory {
public String createDough();
public String createSauce();
public String createCheese();
public String[] createVeggies();
public String createPepperoni();
public String createClam();
}
NYPizzaIngredientFactory.java
public class NYPizzaIngredientFactory implements PizzaIngredientFactory {
public String createDough() {
// return new ThinCrustDough();
return "ThinCrustDough";
}
public String createSauce() {
// return new MarinaraSauce();
return "MarinaraSauce";
}
public String createCheese() {
// return new ReggianoCheese();
return "ReggianoCheese";
}
public String[] createVeggies() {
// String veggies[] = {new Garlic(), new Onion(), new Mushroom(), new RedPepper()};
String veggies[] = {"Garlic", "Onion", "Mushroom", "RedPepper"};
return veggies;
}
public String createPepperoni() {
// return new SlicedPepperoni();
return "SlicedPepperoni";
}
public String createClam() {
// return new FreshClams();
return "FreshClams";
}
}
NYPizzaStore.java
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("뉴욕 스타일 치즈 피자");
}
return pizza;
}
}
CheesePizza.java
public class CheesePizza extends Pizza {
PizzaIngredientFactory ingredientFactory;
public CheesePizza(PizzaIngredientFactory ingredientFactory) {
this.ingredientFactory = ingredientFactory;
}
void prepare() {
System.out.println("준비중" + name);
dough = ingredientFactory.createDough();
sauce = ingredientFactory.createSauce();
cheese = ingredientFactory.createCheese();
}
}
팩토리 메소드 패턴과 추상 팩토리 패턴
팩토리 메소드 패턴
추상 팩토리 패턴
핵심 정리
팩토리를 쓰면 객체 생성을 캡슐화할 수 있다.
간단한 팩토리는 엄밀하게 말해서 디자인 패턴은 아니지만, 클라이언트와 구생 클래스를 분리하는 간단한 기법으로 활용할 수 있다.
팩토리 메소드 패턴은 상속을 활용한다. 객체 생성을 서브클래스에게 맡긴다. 서브클래스는 팩토리 메소드를 구현해서 객체를 생성한다.
추상 팩토리 패턴은 객체 구성을 활용한다. 팩토리 인터페이스에서 선언한 메소드에서 객체 생성이 구현 된다.
모든 팩토리 패턴은 애플리케이션의 구상 클래스 의존성을 줄여줌으로써 느슨한 결합을 도와준다.
팩토리 메소드 패턴은 특정 클래스에서 인스턴스를 만드는 일을 서브클래스에게 넘긴다.
추상 팩토리 패턴은 구상 클래스에 직접 의존하지 않고도 서로 관련된 객체로 이루어진 제품군을 만드는 용도로 쓰인다.
의존성 뒤집기 원칙을 따르면 구상 형식 의존을 피하고 추상화를 지향할 수 있다.
팩토리는 구상 클래스가 아닌 추상클래스와 인터페이스에 맞춰서 코딩할 수 있게 해주는 강력한 기법이다.
'BackEnd' 카테고리의 다른 글
[디자인 패턴] 헤드퍼스트 디자인 패턴 5장 리뷰 (0) | 2023.03.25 |
---|---|
백엔드 서버가 다운 되는 현상 (0) | 2023.03.23 |
[DB] DB 마이그레이션 준비 (0) | 2023.03.20 |
[디자인 패턴] 헤드퍼스트 디자인 패턴 3장 리뷰 (0) | 2023.03.15 |
[디자인 패턴] 헤드퍼스트 디자인 패턴 2장 리뷰 (0) | 2023.03.15 |