ํ‹ฐ์Šคํ† ๋ฆฌ ๋ทฐ

 

ํ”ผ์ž ๊ฐ€๊ฒŒ๋ฅผ ์šด์˜ํ•˜๋ฉฐ ํŒฉํ† ๋ฆฌ ํŒจํ„ด์— ๋Œ€ํ•ด ์•Œ์•„๊ฐ€๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

 

 

 

๋จผ์ € ํ”ผ์ž๋ฅผ ์ฃผ๋ฌธ๋ฐ›์Šต๋‹ˆ๋‹ค.

 

์ฃผ๋ฌธ์„ ๋ฐ›์œผ๋ฉด ํ”ผ์ž ํƒ€์ž…์„ ๊ฒฐ์ •ํ•˜๊ณ ,

์ค€๋น„ํ•˜๊ณ  ํฌ์žฅํ•˜๊ณ  ํ”ผ์ž๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ณผ์ •์ž…๋‹ˆ๋‹ค.

 

protocol Pizza {
    var name: String { get }
    func prepare()
    func bake()
    func cut()
    func box()
}

class CheesePizza: Pizza {
    var name: String { return "Cheese Pizza" }
    func prepare() { print("Preparing \(name)") }
    func bake() { print("Baking \(name)") }
    func cut() { print("Cutting \(name)") }
    func box() { print("Boxing \(name)") }
}

class PepperoniPizza: Pizza {
    var name: String { return "Pepperoni Pizza" }
    func prepare() { print("Preparing \(name)") }
    func bake() { print("Baking \(name)") }
    func cut() { print("Cutting \(name)") }
    func box() { print("Boxing \(name)") }
}

func orderPizza(type: String) -> Pizza {
    var pizza: Pizza

    if type == "cheese" {
        pizza = CheesePizza()
    } else if type == "greek" {
        pizza = GreekPizza()
    } else if type == "pepperoni" {
        pizza = PepperoniPizza()
    } else {
        fatalError("Unsupported pizza type")
    }

    pizza.prepare()
    pizza.bake()
    pizza.cut()
    pizza.box()

    return pizza
}

let cheesePizza = orderPizza(type: "cheese")

 

์ข…๋ฅ˜์— ๋”ฐ๋ผ ๋ฐ˜ํ™˜ํ•  ํ”ผ์ž๋ฅผ ๋ถ„๊ธฐ์ฒ˜๋ฆฌ ํ•˜๊ณ ์žˆ์Šต๋‹ˆ๋‹ค.

 

 

๋ถ„๊ธฐํ•˜์—ฌ ํ”ผ์ž ํƒ€์ž…์„ ๊ฒฐ์ •ํ•˜๋Š” ๋ถ€๋ถ„์„

์บก์Šํ™”ํ•˜์—ฌ ๋”ฐ๋กœ ๋ถ„๋ฆฌ ํ•ด๋‘๋ฉด ์ข‹๋‹ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค.

 

 

์ด์ 

- ๋‹จ์ˆœํ™”๋œ ์ธํ„ฐํŽ˜์ด์Šค ์ œ๊ณต

- ์ˆ˜์ •์„ ํ•˜๋ ค๊ณ  ํ• ๋•Œ ํ•œ๊ตฐ๋ฐ๋งŒ ํ™•์ธํ•˜๋ฉด๋จ

 

 

 

 

 

๊ฐœ์„ ๋œ orderPizza ํ•จ์ˆ˜

 

protocol Pizza {
    var name: String { get }
    func prepare()
    func bake()
    func cut()
    func box()
}

class CheesePizza: Pizza {
    var name: String { return "Cheese Pizza" }
    func prepare() { print("Preparing \(name)") }
    func bake() { print("Baking \(name)") }
    func cut() { print("Cutting \(name)") }
    func box() { print("Boxing \(name)") }
}

class PepperoniPizza: Pizza {
    var name: String { return "Pepperoni Pizza" }
    func prepare() { print("Preparing \(name)") }
    func bake() { print("Baking \(name)") }
    func cut() { print("Cutting \(name)") }
    func box() { print("Boxing \(name)") }
}

// Simple Factory
class SimplePizzaFactory {
    func createPizza(type: String) -> Pizza {
        if type == "cheese" {
            return CheesePizza()
        } else if type == "greek" {
            return GreekPizza()
        } else if type == "pepperoni" {
            return PepperoniPizza()
        } else {
            fatalError("Unsupported pizza type")
        }
    }
}

class PizzaStore {
    let pizzaFactory: SimplePizzaFactory

    init(factory: SimplePizzaFactory) {
        self.pizzaFactory = factory
    }

    func orderPizza(type: String) -> Pizza {
        let pizza = pizzaFactory.createPizza(type: type)

        pizza.prepare()
        pizza.bake()
        pizza.cut()
        pizza.box()

        return pizza
    }
}

let simpleFactory = SimplePizzaFactory()
let pizzaStore = PizzaStore(factory: simpleFactory)

let cheesePizza = pizzaStore.orderPizza(type: "cheese")
let greekPizza = pizzaStore.orderPizza(type: "greek")
let pepperoniPizza = pizzaStore.orderPizza(type: "pepperoni")

 

B ํ”ผ์ž์ง‘์—์„œ ์ด ์ฝ”๋“œ๋ฅผ ์‚ฌ์šฉํ•  ๊ฒฝ์šฐ SimpleFactory (ํ”ผ์ž ์ข…๋ฅ˜) ๋ถ€๋ถ„๋งŒ ์ˆ˜์ •ํ•˜๋ฉด ๋œ๋‹ค.

 

์ด๋ ‡๊ฒŒ ์บก์Šํ™” ํ•˜๋Š”๊ฒƒ์„ 'Simple Factory'

 

๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๋Š” ์—ญํ• ์„

ํ•˜๋‚˜์˜ ํŒฉํ† ๋ฆฌ ํด๋ž˜์Šค๊ฐ€ ์ „๋‹ดํ•˜๋Š” ํ˜•ํƒœ๋ผ๊ณ  ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

 

 

 

๋งŒ์•ฝ

ํ˜„์žฌ ๊ฐ€๊ฒŒ(SimplePizzaFactory)์—์„œ๋Š” cheese, greek, pepperoni 3์ข…๋ฅ˜์ธ๋ฐ,

C ํ”ผ์ž์ง‘์—์„œ๋Š” greekํ”ผ์ž๋Š” ์•ˆํŒ”๊ณ  veggie๋ฅผ ํŒ”๊ณ  ์‹ถ์œผ๋ฉด ์–ด๋–ป๊ฒŒ ํ• ๊นŒ?

 

 

ํ”ผ์ž ์ข…๋ฅ˜๋ฅผ ์ถ”๊ฐ€ํ•˜๊ฒŒ ๋  ๊ฒฝ์šฐ else if type == "์–ด๋–ค ํ”ผ์ž" ์ด๋Ÿฐ์‹์œผ๋กœ ์ˆ˜์ •ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

'๋ณ€๊ฒฝ ์‚ฌํ•ญ์— ๋‹ซํ˜€ ์žˆ์ง€ ์•Š๋‹ค'๊ณ  ๋ณผ ์ˆ˜ ์žˆ์Œ

 

 

 

 

// Simple Factory
class SimplePizzaFactory {
    func createPizza(type: String) -> Pizza {
        if type == "cheese" {
            return CheesePizza()
        } else if type == "greek" {
            return GreekPizza()
        } else if type == "pepperoni" {
            return PepperoniPizza()
        } else {
            fatalError("Unsupported pizza type")
        }
    }
}

 

 

์ €์ˆ˜์ค€ ๋ชจ๋“ˆ์ธ ํ”ผ์ž Class๊ฐ€ ๋ณ€๊ฒฝ๋˜๋ฉด,

๊ณ ์ˆ˜์ค€ ๋ชจ๋“ˆ์ธ SimplePizzaFactory๊ฐ€ ์˜ํ–ฅ์„ ๋ฐ›์œผ๋ฏ€๋กœ DIP ์›์น™์— ์–ด๊ธ‹๋‚จ

-> ์ถ”์ƒํ™” ์ˆ˜์ค€์ด ๋†’์€๊ฒƒ์— ์˜์กดํ•˜๋„๋ก ๊ตฌํ˜„์„ ํ•ด์•ผํ•œ๋‹ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค

 

 

 

์ด ๋ถ€๋ถ„์„

 

๋ณ€๊ฒฝ ์‚ฌํ•ญ์— ๋‹ซํ˜€์žˆ๊ณ ,

ํ™•์žฅ์— ์šฉ์ดํ•˜๊ฒŒ + DIP ์ค€์ˆ˜ํ•˜๋„๋ก ์ˆ˜์ •ํ•œ๋‹ค๋ฉด 

 

 

 

protocol Pizza {
    var name: String { get }
    func prepare()
    func bake()
    func cut()
    func box()
}

class NYStyleCheesePizza: Pizza {
    var name: String { return "NYStyle Cheese Pizza" }
    func prepare() { print("Preparing \(name)") }
    func bake() { print("Baking \(name)") }
    func cut() { print("Cutting \(name)") }
    func box() { print("Boxing \(name)") }
}

class NYStylePepperoniPizza: Pizza {
    var name: String { return "NYStyle Pepperoni Pizza" }
    func prepare() { print("Preparing \(name)") }
    func bake() { print("Baking \(name)") }
    func cut() { print("Cutting \(name)") }
    func box() { print("Boxing \(name)") }
}

protocol PizzaFactory {
    func createPizza() -> Pizza
}

class NYStyleCheesePizzaFactory: PizzaFactory {
    func createPizza() -> Pizza {
        return CheesePizza()
    }
}

class NYStylePepperoniPizzaFactory: PizzaFactory {
    func createPizza() -> Pizza {
        return PepperoniPizza()
    }
}

class PizzaStore {
    let pizzaFactory: PizzaFactory

    init(factory: PizzaFactory) {
        self.pizzaFactory = factory
    }

    func orderPizza() -> Pizza {
        let pizza = pizzaFactory.createPizza()

        pizza.prepare()
        pizza.bake()
        pizza.cut()
        pizza.box()

        return pizza
    }
}

let cheeseFactory = CheesePizzaFactory()
let pepperoniFactory = PepperoniPizzaFactory()

let cheesePizzaStore = PizzaStore(factory: cheeseFactory)
let pepperoniPizzaStore = PizzaStore(factory: pepperoniFactory)

let cheesePizza = cheesePizzaStore.orderPizza()
let pepperoniPizza = pepperoniPizzaStore.orderPizza()

 

createPizza๋ฅผ ์ธํ„ฐํŽ˜์ด์Šค์— ์„ ์–ธํ•ด๋‘๊ณ , ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ฑ„ํƒํ•˜์—ฌ 

ํ•˜์œ„ ํ”ผ์ž ํด๋ž˜์Šค(NYStyleCheesePizzaFactory)์—์„œ create์˜ ๊ตฌ์ฒด์ ์ธ ๊ตฌํ˜„์„ ํ•˜๋„๋ก ํ•ด์คฌ์Šต๋‹ˆ๋‹ค

 

๊ทธ๋Ÿฌ๊ณ  PizzaStore(factory: PizzaFactroy) ์ด๋Ÿฐ์‹์˜ ์™ธ๋ถ€ ์˜์กด์„ฑ ์ฃผ์ž…(DI)์„ ํ†ตํ•ด

์ €์ˆ˜์ค€ ๋ชจ๋“ˆ(ํ”ผ์ž ์ข…๋ฅ˜)๊ฐ€ ๋ณ€๊ฒฝ๋˜์–ด๋„ ๊ณ ์ˆ˜์ค€ ๋ชจ๋“ˆ(PizzaStore)๊ฐ€ ๋ณ€๊ฒฝ๋˜์ง€ ์•Š๋„๋ก ์ˆ˜์ • ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

 

 

 

 

์œ„ ๋ฐฉ์‹์ด 'ํŒฉํ† ๋ฆฌ ํŒจํ„ด(ํŒฉํ† ๋ฆฌ ๋ฉ”์†Œ๋“œ ํŒจํ„ด)'์œผ๋กœ

ํด๋ž˜์Šค ์ธ์Šคํ„ดํŠธ ๋งŒ๋“œ๋Š” ์ผ์„ ์„œ๋ธŒ ํด๋ž˜์Šค์—์„œ ํ•˜๋„๋ก ์„ค๊ณ„ํ•˜๋Š” ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค.

 

PizzaFactory ๋‚ด๋ถ€์—์„œ ์–ด๋–ค ํ”ผ์ž๋“  ์ƒ๊ด€์—†์ด ๋‹ค ํ”ผ์ž๋ฅผ ๋ฐ˜ํ™˜ ํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ์œ ์—ฐํ•˜๋‹ค๊ณ  ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

 

 

 

 

 

 

 

๋งˆ์ง€๋ง‰์œผ๋กœ

 

์ถ”์ƒ ํŒฉํ† ๋ฆฌ ํŒจํ„ด

: ๊ตฌ์ƒ ํด๋ž˜์Šค์— ์˜์กดํ•˜์ง€ ์•Š๊ณ ๋„ ์„œ๋กœ ์˜์กด์ ์ธ ๊ฐ์ฒด๋กœ ์ด๋ฃจ์–ด์ง„ ์ œํ’ˆ๊ตฐ์„ ์ƒ์‚ฐํ•˜๋Š” ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ œ๊ณตํ•˜๋Š” ํŒจํ„ด

-> A ๊ฐ์ฒด(์‹œ์นด๊ณ  ํ”ผ์ž)์™€ B ๊ฐ์ฒด(๋‰ด์š• ํ”ผ์ž) ๋ชจ๋‘ ์“ฐ์ด๋Š” ์š”์†Œ(ํ”ผ์ž ๋„ํ•‘ ์žฌ๋ฃŒ)๋ฅผ ์ธํ„ฐํŽ˜์ด์Šค๋กœ ์„ ์–ธํ•ด๋‘๋Š”๊ฑธ ์ถ”์ƒํŒฉํ† ๋ฆฌ ํŒจํ„ด์ด๋ผ๊ณ  ํ•˜๋Š”๊ฒƒ ๊ฐ™์•„์š”

 

 

 

 

 

๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค

 

 

๋Œ“๊ธ€