간단한 팩토리(Simple Factory)
간단한 팩토리는 디자인 패턴이라고 할 수는 없지만 프로그래밍을 하는데 있어서
자주 쓰이는 관용구에 가깝다.
new의 문제점
"new"는 “구상 객체”를 뜻함
new를 사용하는 것은 구상 클래스의 인스턴스를 만드는 것으로 구상 클래스를 바탕으로
코딩을 하면 나중에 코드를 수정해야 할 가능성이 높아지고 유연성이 떨어지게 됨
Pizza orderPizza(){
Pizza pizza = new Pizza();
// 유연성을 감안하여 추상 클래스 또는 인터페이스로 만드는 것이 좋지만 추상클래스나
// 인터페이스로는 직접 인스턴스를 만들 수 없음
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
return pizza;
}
1. 피자 종류를 고르고 피자를 만들기 위한 코드의 추가
Pizza orderPizza(String type){ // 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인스턴수 변수에 그 인스턴스를 대입. 여기에 있는 모든 피자 클래스는 pizza인터페이스를 구현
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
return pizza;
}
2. 피자 종류를 추가 해야 할 때
Pizza orderPizza(String type){ // 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();
} else if (type.equals("clam"){
pizza = new PepperoniPizza();
} else if (type.equals("veggie"){
pizza = new PepperoniPizza();
}
// 이 코드는 코드 변경에 대해 닫혀있지 않기 때문에 피자가게에서 메뉴를 변경하려면 이코드를 직접 고쳐야 함
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////// 바뀌지 않는 부분/////////////////////
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
return pizza;
////////////////////////////////////////////////////////////
}
3. 객체 생성 부분을 캡슐화
Pizza orderPizza(){
Pizza pizza;
// 바뀌는 객체 생성 코드를 orderPizza 메소드에서 빼냄
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
return pizza;
}
4. 피자를 만들기 위한 객체 생성 부분을 전담할 간단한
피자 팩토리 클래스
public class SimplePizzaFactory{
public Pizza createPizza(String type){
// createPizza() 메소드를 정의. 이 메소드는 클라이언트에서 새로운 객체의 인스턴스를 만들때 호출하는 메소드
Pizza pizza = null;
if (type.equals("cheese")){
pizza = new CheesePizza();
} else if (type.equals("pepperoni"){
pizza = new PepperoniPizza();
} else if (type.equals("clam"){
pizza = new PepperoniPizza();
} else if (type.equals("veggie"){
pizza = new PepperoniPizza();
}
return pizza;
}
}
5. 팩토리를 이용해서 피자 객체를 생성하도록 수정
public class PizzaStore{
SimplePizzaFactory factory;
// PizzaStore에 SimplePizzaFactory에 대한 레퍼런스를 저장
public PizzaStore(SimplePizzaFactory factory{
// PizzaStore의 생성자에 팩토리 객체가 전달
Pizza pizza;
pizza = factory.createPizza(type);
// new 연산자 대신 팩토리 객체에 있는 create메소드를 사용
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
return pizza;
}
// 기타 메소드
}

<최종의 클래스 다이어그램>
디자인 패턴에 대해 이야기할 때 “인터페이스를 구현한다”는 표현이 나온다고 해서 항상
“클래스를 선언하는 부분에서 implements 키워드를 써서 어떤 자바 인터페이스를 구현하는 클래스를 만든다”라고 생각하면 안됨. 일반적으로 어떤 상위 형식(클래스 일수도 있고
인터페이스 일 수도 있음)
출처 : Head First Design Patterns
댓글 없음:
댓글 쓰기