zoukankan      html  css  js  c++  java
  • 设计模式学习

    工厂模式:

    定义了一个创建对象的接口,但由它的子类决定实例化哪一个对象。工厂方法将对象的实例化延迟到了子类。

    模式组成:

    • 一组使用者:父类定义一个创建对象的接口及其他通用接口,子类负责创建对象接口的具体实现(在案例中为 PizzaStore 及 NYPizzaStore
    • 一组产品类:(在案例中为 抽象Pizza类及其具体实现的子类)

    注:

    1.   每一个使用者的子类负责创建一个(组)相似对象。

    UML 类图:

    代码具体实现:

    1、 对象的创建者: PizzaStore 类

    // pizza Store 父类:包含了创建pizza(createPizza)这个抽象方法
    class PizzaStore {
        // 包含了一个产品的抽象类 和 一个简单工厂
        var pizza:Pizza = Pizza()
        
        // 提供 pizza 方法
        func orderPizza(pizzatype: Pizzatype) {
            // 获取相应商店创建的 pizza 对象的引用
            self.pizza = createPizza(pizzatype)
            
            // 产品的行为
            pizza.prepare()
            pizza.bake()
            pizza.cut()
            pizza.box()
        }
        
        // 创建一个 负责创建对象的接口,但是它由实现子类具体实现
        func createPizza(pizzatype: Pizzatype) -> Pizza {
            return Pizza()
        }
    }
    
    // 纽约Pizza商店:负责创建纽约风味的Pizza
    class NYPizzaStore: PizzaStore {
        // 具体实现 负责创建对象的接口
        override func createPizza(pizzatype: Pizzatype) -> Pizza {
            switch pizzatype {
            case Pizzatype.Cheese:
                pizza = NYCheesePizza()
            case Pizzatype.Clam:
                pizza = NYClamPizza()
            }
            
            return pizza
        }
    }
    
    // 芝加哥Pizza商店:负责创建芝加哥风味的Pizza
    class ChicagoPizzaStore: PizzaStore {
        // 具体实现 负责创建对象的接口
        override func createPizza(pizzatype: Pizzatype) -> Pizza {
            switch pizzatype {
            case Pizzatype.Cheese:
                pizza = ChicagoCheesePizza()
            case Pizzatype.Clam:
                pizza = ChicagoClamPizza()
            }
            
            return pizza
        }
    }

    2、对象类:

    // 对象的父类
    class Pizza {
        var name:String  = ""
        var dough:String = ""
        var sauce:String = ""
        var toppings:[String] = []
        
        // 准备pizza 方法
        func prepare() {
            println("正在准备 (name) ...")
            println("Tossing dough...")
            println("加入 (sauce)...")
            for topping:String in toppings {
                println("   (topping)")
            }
        }
        
        func box() {
            println("正在打包...
    ")
        }
        
        func bake() {
            println("正在烘焙...")
        }
        
        func cut() {
            println("正在裁剪...")
        }
    }
    
    // 一个纽约风味的 Cheese Pizza; 它与 纽约风味的 Clem Pizza 同为一组
    class NYCheesePizza: Pizza {
        override init() {
            super.init()
            self.name = "纽约风味的 Cheese Pizza"
            self.dough = "Thin Crust Dough"
            self.sauce = "草莓 酱汁"
            
            toppings.append("Grated Reggino Cheese")
        }
    }
    
    // 一个纽约风味的 Clam Pizza
    class NYClamPizza: Pizza {
        override init() {
            super.init()
            self.name = "纽约风味的 NYClam Pizza"
            self.dough = "Low Crust Dough"
            self.sauce = "樱桃 酱汁"
            
            toppings.append("Grated Reggino Clam")
        }
    }
    
    // 一个芝加哥风味的 Cheese Pizza; 它与 芝加哥风味的 Clem Pizza 同为一组
    class ChicagoCheesePizza: Pizza {
        override init() {
            super.init()
            self.name = "芝加哥风味的 Cheese Pizza"
            self.dough = "Thin Crust Dough"
            self.sauce = "芒果 酱汁"
            
            toppings.append("Grated Reggino Cheese")
        }
        
        // 子类也可以覆盖父类的方法
        override func cut() {
            println("正在裁剪:裁剪成方块状...")
        }
    }
    
    // 一个芝加哥风味的 Clam Pizza
    class ChicagoClamPizza: Pizza {
        override init() {
            super.init()
            self.name = "芝加哥风味的 Clam Pizza"
            self.dough = "Low Crust Dough"
            self.sauce = "烤肉 酱汁"
            
            toppings.append("Grated Reggino Clam")
        }
        
        // 子类也可以覆盖父类的方法
        override func cut() {
            println("正在裁剪:裁剪成方块状...")
        }
    }

    3、测试代码:

    // 先访问 纽约Pizza商店
    var pizzaStore: PizzaStore = NYPizzaStore()
    // 买一个纽约风味的CheesePizza
    /* 
    先调用了 NYPizzaStore 的 orderPizza 方法,再由 orderPizza 方法调用 createPizza 方法;
    其中 orderPizza 方法是父类创建的,为子类所共有使用,orderPizza 并不需要知道这个 Pizza 到底是哪一个种类的,只需要知道这是一个 Pizza 能进行准备、裁剪等行为就足够了
    而 createPizza 方法则是子类自己按照相应的情况具体实现去创建相应风味的 Pizza;
    */
    pizzaStore.orderPizza(Pizzatype.Cheese)
    
    // 再访问 芝加哥Pizza商店,买一个芝加哥风味的ClamPizza
    pizzaStore = ChicagoPizzaStore()
    pizzaStore.orderPizza(Pizzatype.Clam)

    4、测试结果

     

  • 相关阅读:
    JVM精进之路
    Java8-java.time-常用API
    Java代码精进
    Java8——jdk——java.time包
    Java8——Optional
    Java8——Stream
    Java8——Lambda表达式
    Java高级-反射
    重新学习SpringMVC——补充
    LeetCode677. 键值映射(相关话题:Trie前缀树)
  • 原文地址:https://www.cnblogs.com/ziyeSky/p/4494846.html
Copyright © 2011-2022 走看看