代码改变世界

工厂模式

2015-04-24 11:50  foolbread-老陈  阅读(152)  评论(0编辑  收藏  举报

    工厂模式:定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法让类把实例化推迟到子类。——《HEAD FIRST 设计模式》

    我的golang代码:

package factory

import (
    "fmt"
)

type PizzaStore interface {
    createPizza(t string) Pizza
    OrderPizza(t string) Pizza
}

type Pizza interface {
    prepare()
    bake()
    cut()
    box()
}

///////////////////////////////////////////
type NYStylePizzaStore struct {
}

func (f *NYStylePizzaStore) OrderPizza(t string) Pizza {
    var r Pizza
    r = f.createPizza(t)

    r.prepare()
    r.bake()
    r.cut()
    r.box()

    return r
}

func (f *NYStylePizzaStore) createPizza(t string) Pizza {
    switch t {
    case "cheese":
        return NewNYStyleCheesePizaa()
    case "veggie":
        return NewNYStyleVeggiePizza()
    case "clam":
        return NewNYStyleClamPizza()
    case "pepperoni":
        return NewNYStylePepperoniPizza()
    }

    return nil
}

type ChicagoStylePizzaStore struct {
}

func (f *ChicagoStylePizzaStore) OrderPizza(t string) Pizza {
    var r Pizza
    r = f.createPizza(t)

    r.prepare()
    r.bake()
    r.cut()
    r.box()

    return r
}

func (f *ChicagoStylePizzaStore) createPizza(t string) Pizza {
    switch t {
    case "cheese":
        return NewChicagoStyleCheesePizza()
    case "veggie":
        return NewChicagoStyleVeggiePizza()
    case "clam":
        return NewChicagoStyleClamPizza()
    case "pepperoni":
        return NewChicagoStylePepperoniPizza()
    }

    return nil
}

/////////////////////////////////////////////

type NYStyleCheesePizza struct {
    name     string
    dough    string
    sauce    string
    toppings []string
}

func NewNYStyleCheesePizaa() *NYStyleCheesePizza {
    r := new(NYStyleCheesePizza)
    r.name = "NY Style Sauce and Cheese Pizza"
    r.dough = "Thin Crust Dough"
    r.sauce = "Marinara Sauce"

    r.toppings = append(r.toppings, "Grated Reggiano Chees")

    return r
}

func (f *NYStyleCheesePizza) prepare() {
    fmt.Println("Preparing", f.name)
    fmt.Println("Tossing dough...")
    fmt.Println("Adding sauce...")
    fmt.Println("Adding  toppings:")
    for k, _ := range f.toppings {
        fmt.Println(" ", f.toppings[k])
    }
}

func (f *NYStyleCheesePizza) bake() {
    fmt.Println("Bake for 25 minutes at 350")
}

func (f *NYStyleCheesePizza) cut() {
    fmt.Println("Cutting the pizza into diagonal slices")
}

func (f *NYStyleCheesePizza) box() {
    fmt.Println("Place pizza in official PizzaStore box")
}

type NYStyleVeggiePizza struct {
    name     string
    dough    string
    sauce    string
    toppings []string
}

func NewNYStyleVeggiePizza() *NYStyleVeggiePizza {
    r := new(NYStyleVeggiePizza)
    r.name = "NY Style Veggie Pizza"
    r.dough = "Thin Crust Dough"
    r.sauce = "Marinara Sauce"

    r.toppings = append(r.toppings, "Grated Reggiano Cheese")
    r.toppings = append(r.toppings, "Garlic")
    r.toppings = append(r.toppings, "Onion")
    r.toppings = append(r.toppings, "Mushrooms")
    r.toppings = append(r.toppings, "Red Pepper")

    return r
}

func (f *NYStyleVeggiePizza) prepare() {
    fmt.Println("Preparing", f.name)
    fmt.Println("Tossing dough...")
    fmt.Println("Adding sauce...")
    fmt.Println("Adding  toppings:")
    for k, _ := range f.toppings {
        fmt.Println(" ", f.toppings[k])
    }
}

func (f *NYStyleVeggiePizza) bake() {
    fmt.Println("Bake for 25 minutes at 350")
}

func (f *NYStyleVeggiePizza) cut() {
    fmt.Println("Cutting the pizza into diagonal slices")
}

func (f *NYStyleVeggiePizza) box() {
    fmt.Println("Place pizza in official PizzaStore box")
}

type NYStyleClamPizza struct {
    name     string
    dough    string
    sauce    string
    toppings []string
}

func NewNYStyleClamPizza() *NYStyleClamPizza {
    r := new(NYStyleClamPizza)
    r.name = "NY Style Clam Pizza"
    r.dough = "Thin Crust Dough"
    r.sauce = "Marinara Sauce"

    r.toppings = append(r.toppings, "Grated Reggiano Cheese")
    r.toppings = append(r.toppings, "Fresh Clams from Long Island Sound")

    return r
}

func (f *NYStyleClamPizza) prepare() {
    fmt.Println("Preparing", f.name)
    fmt.Println("Tossing dough...")
    fmt.Println("Adding sauce...")
    fmt.Println("Adding  toppings:")
    for k, _ := range f.toppings {
        fmt.Println(" ", f.toppings[k])
    }
}

func (f *NYStyleClamPizza) bake() {
    fmt.Println("Bake for 25 minutes at 350")
}

func (f *NYStyleClamPizza) cut() {
    fmt.Println("Cutting the pizza into diagonal slices")
}

func (f *NYStyleClamPizza) box() {
    fmt.Println("Place pizza in offcial PizzaStore box")
}

type NYStylePepperoniPizza struct {
    name     string
    dough    string
    sauce    string
    toppings []string
}

func NewNYStylePepperoniPizza() *NYStylePepperoniPizza {
    r := new(NYStylePepperoniPizza)
    r.name = "NY Style Pepperoni Pizza"
    r.dough = "Thin Crust Dough"
    r.sauce = "Marinara Sauce"

    r.toppings = append(r.toppings, "Grated Reggiano Cheese")
    r.toppings = append(r.toppings, "Sliced Pepperoni")
    r.toppings = append(r.toppings, "Garlic")
    r.toppings = append(r.toppings, "Onion")
    r.toppings = append(r.toppings, "Mushrooms")
    r.toppings = append(r.toppings, "Red Pepper")

    return r
}

func (f *NYStylePepperoniPizza) prepare() {
    fmt.Println("Preparing", f.name)
    fmt.Println("Tossing dough...")
    fmt.Println("Adding sauce...")
    fmt.Println("Adding  toppings:")
    for k, _ := range f.toppings {
        fmt.Println(" ", f.toppings[k])
    }
}

func (f *NYStylePepperoniPizza) bake() {
    fmt.Println("Bake for 25 minutes at 350")
}

func (f *NYStylePepperoniPizza) cut() {
    fmt.Println("Cutting the pizza into diagonal slices")
}

func (f *NYStylePepperoniPizza) box() {
    fmt.Println("Place pizza in offcial PizzaStore box")
}

type ChicagoStyleCheesePizza struct {
    name     string
    dough    string
    sauce    string
    toppings []string
}

func NewChicagoStyleCheesePizza() *ChicagoStyleCheesePizza {
    r := new(ChicagoStyleCheesePizza)
    r.name = "Chicago Style Deep Dish Cheese Pizza"
    r.dough = "Extra Thick Crust Dough"
    r.sauce = "Plum Tomato Sauce"

    r.toppings = append(r.toppings, "Shredded Mozzarella Cheese")

    return r
}

func (f *ChicagoStyleCheesePizza) prepare() {
    fmt.Println("Preparing", f.name)
    fmt.Println("Tossing dough...")
    fmt.Println("Adding sauce...")
    fmt.Println("Adding  toppings:")
    for k, _ := range f.toppings {
        fmt.Println(" ", f.toppings[k])
    }
}

func (f *ChicagoStyleCheesePizza) bake() {
    fmt.Println("Bake for 25 minutes at 350")
}

func (f *ChicagoStyleCheesePizza) cut() {
    fmt.Println("Cutting the pizza into diagonal slices")
}

func (f *ChicagoStyleCheesePizza) box() {
    fmt.Println("Place pizza in offcial PizzaStore box")
}

type ChicagoStylePepperoniPizza struct {
    name     string
    dough    string
    sauce    string
    toppings []string
}

func NewChicagoStylePepperoniPizza() *ChicagoStylePepperoniPizza {
    r := new(ChicagoStylePepperoniPizza)
    r.name = "Chicago Style Pepperoni Pizza"
    r.dough = "Extra Thick Crust Dough"
    r.sauce = "Plum Tomato Sauce"

    r.toppings = append(r.toppings, "Shredded Mozzarella Cheese")
    r.toppings = append(r.toppings, "Black Olives")
    r.toppings = append(r.toppings, "Spinach")
    r.toppings = append(r.toppings, "Eggplant")
    r.toppings = append(r.toppings, "Sliced Pepperoni")

    return r
}

func (f *ChicagoStylePepperoniPizza) prepare() {
    fmt.Println("Preparing", f.name)
    fmt.Println("Tossing dough...")
    fmt.Println("Adding sauce...")
    fmt.Println("Adding  toppings:")
    for k, _ := range f.toppings {
        fmt.Println(" ", f.toppings[k])
    }
}

func (f *ChicagoStylePepperoniPizza) bake() {
    fmt.Println("Bake for 25 minutes at 350")
}

func (f *ChicagoStylePepperoniPizza) cut() {
    fmt.Println("Cutting the pizza into diagonal slices")
}

func (f *ChicagoStylePepperoniPizza) box() {
    fmt.Println("Place pizza in offcial PizzaStore box")
}

type ChicagoStyleClamPizza struct {
    name     string
    dough    string
    sauce    string
    toppings []string
}

func NewChicagoStyleClamPizza() *ChicagoStyleClamPizza {
    r := new(ChicagoStyleClamPizza)
    r.name = "Chicago Style Clam Pizza"
    r.dough = "Extra Thick Crust Dough"
    r.sauce = "Plum Tomato Sauce"

    r.toppings = append(r.toppings, "Shredded Mozzarella Cheese")
    r.toppings = append(r.toppings, "Frozen Clams from Chesapeake Bay")

    return r
}

func (f *ChicagoStyleClamPizza) prepare() {
    fmt.Println("Preparing", f.name)
    fmt.Println("Tossing dough...")
    fmt.Println("Adding sauce...")
    fmt.Println("Adding  toppings:")
    for k, _ := range f.toppings {
        fmt.Println(" ", f.toppings[k])
    }
}

func (f *ChicagoStyleClamPizza) bake() {
    fmt.Println("Bake for 25 minutes at 350")
}

func (f *ChicagoStyleClamPizza) cut() {
    fmt.Println("Cutting the pizza into diagonal slices")
}

func (f *ChicagoStyleClamPizza) box() {
    fmt.Println("Place pizza in offcial PizzaStore box")
}

type ChicagoStyleVeggiePizza struct {
    name     string
    dough    string
    sauce    string
    toppings []string
}

func NewChicagoStyleVeggiePizza() *ChicagoStyleVeggiePizza {
    r := new(ChicagoStyleVeggiePizza)
    r.name = "Chicago Deep Dish Veggie Pizza"
    r.dough = "Extra Thick Crust Dough"
    r.sauce = "Plum Tomato Sauce"

    r.toppings = append(r.toppings, "Shredded Mozzarella Cheese")
    r.toppings = append(r.toppings, "Black Olives")
    r.toppings = append(r.toppings, "Spinach")
    r.toppings = append(r.toppings, "Eggplant")

    return r
}

func (f *ChicagoStyleVeggiePizza) prepare() {
    fmt.Println("Preparing", f.name)
    fmt.Println("Tossing dough...")
    fmt.Println("Adding sauce...")
    fmt.Println("Adding  toppings:")
    for k, _ := range f.toppings {
        fmt.Println(" ", f.toppings[k])
    }
}

func (f *ChicagoStyleVeggiePizza) bake() {
    fmt.Println("Bake for 25 minutes at 350")
}

func (f *ChicagoStyleVeggiePizza) cut() {
    fmt.Println("Cutting the pizza into diagonal slices")
}

func (f *ChicagoStyleVeggiePizza) box() {
    fmt.Println("Place pizza in offcial PizzaStore box")
}

     个人感悟:待定。