반응형

가정) 문제 : 몇몇 프랜차이즈에서 값싼 재료(치즈, 도우 등)를 바꿔서 원가를 줄이고 마진을 올린다고 합니다.

어떻게 하면 프랜차이즈에서 좋은 재료를 사용하도록 관리할 수 있을까요?

 

해결 : 원재료를 생성하는 공장(factory)을 만들고 프랜차이즈까지 분점까지 재료를 배달하면 되겠죠?

 

하지만 지역마다 쓰는 재료들이 약간씩 다릅니다 (경상도 : 열무김치, 전라도 : 배추김치,  충청도 : 물김치 .. 같은 느낌)

.

.

 

코드 작성 전 확인 

.

.

.

피자 재료 공장 

//피자 재료 팩토리 (인터페이스)
public interface PizzaMaterialFactory {
     //도우와 치즈를 리턴하는 메소드를 구현해야함.
     Dough createDough();
     Cheese createCheese();
}

//뉴욕에 있는 프랜차이즈용 재료 공장
public class NYPizzaMaterialFactory implements PizzaMaterialFactory{
    @Override
    public Dough createDough() {
        //뉴욕 도우 : 얇은 도우를 리턴함
        return new ThinDough();
    }

    @Override
    public Cheese createCheese() {
        //뉴욕 도우 : 맛있는 치즈를 리턴함
        return new DeliciousCheese();
    }
}

 

재료 종류별 인터페이스 및 구현

//종류별 도우가 다르기 때문에 도우 interface를 만들어서 각 종류별 도우를 생산
public interface Dough {
    String toString();
}

//얇은 도우를 생상하기위해 dough 리턴하는 Dough 인터페이스를 구현함.
public class ThinDough implements Dough{
    public String toString() {
        return "얇은 도우";
    }
}


//치즈도 마찬가지
public interface Cheese {
    String toString();
}

public class DeliciousCheese implements Cheese{
    public String toString() {
        return "맛있는 치즈";
    }
}

 

피자 추상 클래스

//피자 추상클래스
public abstract class Pizza {

    String name;
    //도우와 치즈의 종류를 서브클래스의 prepare()에서 구현해줄 것임. 
    Dough dough;
    Cheese cheese;
    ArrayList toppings = new ArrayList();

    //달라진 점 : 추상메소드로 구현할 서브클래스에서 구현.
    abstract void prepare();

    void bake() {
        Log.d("abcd","반죽");
    }
    void cut() {
        Log.d("abcd","자르기");
    }
    void box() {
        Log.d("abcd","포장");
    }
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Pizza{" +
                "name='" + name + '\'' +
                ", dough=" + dough +
                ", cheese=" + cheese +
                ", toppings=" + toppings +
                '}';
    }
}



//뉴욕 피자 서브클래스
public class NYCheesePizza extends Pizza{
    //재료 공장
    PizzaMaterialFactory pizzaMaterialFactory;

    //생성자
    public NYCheesePizza(PizzaMaterialFactory pizzaMaterialFactory) {
        this.pizzaMaterialFactory = pizzaMaterialFactory;
    }

    @Override
    void prepare() {
        //피자 추상클래스에서 받은 cheese와 dough를 정의.
        cheese = pizzaMaterialFactory.createCheese();
        dough = pizzaMaterialFactory.createDough();
    }
}

 

피자가게 

//피자 추상클래스 (바뀐 것 없음.)
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{
    @Override
    Pizza createPizza(String item) {
        //피자 추상클래스
        Pizza pizza = null;
        //뉴욕 피자 재료 공장 (다형성)
        PizzaMaterialFactory pizzaMaterialFactory = new NYPizzaMaterialFactory();
        if (item.equals("cheese")) {
            //생성자로 뉴욕피자재료공장 클래스를 상속한 factory를 인자로 넣어줌.
            pizza = new NYCheesePizza(pizzaMaterialFactory);
            pizza.setName("뉴욕 치즈 피자");
        }

        return pizza;
    }
}

 

메인액티비티

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        PizzaStore pizzaStore = new NYPizzaStore();

        Pizza pizza = pizzaStore.orderPizza("cheese");
        Log.d("abcd","what pizza : "+pizza.toString());
    }
}

결과 :

D/abcd: 반죽
        D/abcd: 자르기
        포장
        what pizza : Pizza{name='뉴욕 치즈 피자', dough=얇은 도우, cheese=맛있는 치즈, toppings=[]}

.

.

.

 

코드 작성 후 다시 확인

 


코틀린

 

피자재료공장

//
interface PizzaMaterialFactory  {
    fun createDough() : Dough
    fun createCheese() : Cheese
}


//
class NYMaterialFactory : PizzaMaterialFactory {
    override fun createDough(): Dough {
        return ThinDough()
    }

    override fun createCheese(): Cheese {
        return DeliciousCheese()
    }
}

피자재료종류

interface Dough {
    override fun toString() : String
}

//
interface Cheese {
    override fun toString() : String
}


//
class ThinDough : Dough {
    override fun toString(): String {
        return "얇은 도우"
    }
}


//
class DeliciousCheese : Cheese{
    override fun toString(): String {
        return "맛있는 치즈"
    }
}

피자가게

class NYPizzaStore : PizzaStore() {
    override fun createPizza(type: String): Pizza {

        var pizza:Pizza? = null
        val pizzaMaterialFactory:PizzaMaterialFactory = NYMaterialFactory()
        if (type == "cheese") {
            pizza = NYCheesePizza(pizzaMaterialFactory)
            pizza.name = "뉴욕치즈피자"
        }
        return pizza!!

    }
}

피자

abstract class Pizza {

    var name:String? = null
    var dough:Dough? = null
    var cheese:Cheese? = null
    var toppings:ArrayList<String>? = null

    abstract fun prepare()

    open fun bake() {
        Log.d("abcd", "반죽")
    }

    open fun cut() {
        Log.d("abcd", "자르기")
    }

    open fun box() {
        Log.d("abcd", "포장")
    }

}




//
class NYCheesePizza constructor(pizzaMaterialFactory: PizzaMaterialFactory) : Pizza() {

    var pizzaMaterial:PizzaMaterialFactory? = null

    init {
        pizzaMaterial = pizzaMaterialFactory
    }

    override fun prepare() {
        cheese = pizzaMaterial?.createCheese()
        dough = pizzaMaterial?.createDough()
    }
}

.

.

.

추상 팩토리 패턴 : 추상 팩토리 패턴에서는 인터페이스를 이용하여 서로 연관된, 또는 의존하는 객체를
구상 클래스를 지정하지 않고도  생성할 수 있습니다.
반응형

+ Recent posts