zoukankan      html  css  js  c++  java
  • 工厂模式

    概念:

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

    上一篇博文我们了解了简单工厂模式,我们创建一个简单的工厂去创建披萨,但是我们只能创建一种风味的披萨,比如原生

    风味的披萨,如果我们想再创建一种风味的披萨工厂,我们只能再创建一个对应的工厂。此时我们的披萨也不得不跟着也要

    创建一个,这样程序就耦合了。所以我们来看看如何用工厂模式解决这个问题。

    代码实现: 

      1,还是先定义披萨接口以及原生风味和纽约风味各自两种披萨(奶酪和蛤蜊)

    package factorymode.factory;
    
    /**
     * @ClassName Pizaa
     * @Description 定义披萨接口
     * @Author liuyi
     * @Date 2020/6/15 20:50
     * @Version 1.0
     */
    public interface Pizaa {
    
        //准备
        public void prepare();
        //烘烤
        public void bake();
        //切片
        public void cut();
        //包装
        public void box();
    
    }
    

      

    package factorymode.factory;
    /**
     * @ClassName CheesePizza
     * @Description 奶酪披萨
     * @Author liuyi
     * @Date 2020/6/15 20:58
     * @Version 1.0
     */
    public class CheesePizza implements Pizaa{
        @Override
        public void prepare() {
            System.out.println("准备生产奶酪披萨");
        }
    
        @Override
        public void bake() {
            System.out.println("烘烤奶酪披萨");
        }
    
        @Override
        public void cut() {
            System.out.println("切片奶酪披萨");
        }
    
        @Override
        public void box() {
            System.out.println("包装奶酪披萨");
        }
    }
    

      

    package factorymode.factory;
    /**
     * @ClassName ClamPizza
     * @Description 蛤蜊披萨
     * @Author liuyi
     * @Date 2020/6/15 21:00
     * @Version 1.0
     */
    public class ClamPizza implements Pizaa{
        @Override
        public void prepare() {
            System.out.println("准备生产蛤蜊披萨");
        }
    
        @Override
        public void bake() {
            System.out.println("烘烤蛤蜊披萨");
        }
    
        @Override
        public void cut() {
            System.out.println("切片蛤蜊披萨");
        }
    
        @Override
        public void box() {
            System.out.println("包装蛤蜊披萨");
        }
    }
    

      

    package factorymode.factory;
    
    /**
     * @ClassName CheesePizza
     * @Description 奶酪披萨
     * @Author liuyi
     * @Date 2020/6/15 20:58
     * @Version 1.0
     */
    public class NewYorkCheesePizza implements Pizaa{
        @Override
        public void prepare() {
            System.out.println("准备生产纽约风味奶酪披萨");
        }
    
        @Override
        public void bake() {
            System.out.println("烘烤纽约风味奶酪披萨");
        }
    
        @Override
        public void cut() {
            System.out.println("切片纽约风味奶酪披萨");
        }
    
        @Override
        public void box() {
            System.out.println("包装纽约风味奶酪披萨");
        }
    }
    

      

    package factorymode.factory;
    
    /**
     * @ClassName ClamPizza
     * @Description 蛤蜊披萨
     * @Author liuyi
     * @Date 2020/6/15 21:00
     * @Version 1.0
     */
    public class NewYorkClamPizza implements Pizaa{
        @Override
        public void prepare() {
            System.out.println("准备生产蛤蜊披萨");
        }
    
        @Override
        public void bake() {
            System.out.println("烘烤蛤蜊披萨");
        }
    
        @Override
        public void cut() {
            System.out.println("切片蛤蜊披萨");
        }
    
        @Override
        public void box() {
            System.out.println("包装蛤蜊披萨");
        }
    }

      2,定义一个创建对象的抽象类,这里为什么不是接口,其实不管是接口还是抽象类都是多态的一种呈现,这里用抽象类

    的目的就是固定生产披萨的流程准备,烘烤,切面,封装(不能让我们的加盟店偷工减料,砸了自己的招牌。。。。)

    package factorymode.factory;
    /**
    * @ClassName PizzaStrore
    * @Description 定义购买披萨的商店的抽象类
    * @Author liuyi
    * @Date 2020/6/15 21:07
    * @Version 1.0
    */
    public abstract class PizzaStrore {
    //订购披萨方法
    public Pizaa orderPizza(String type){
    Pizaa pizaa;
    pizaa = createPizza(type);
    pizaa.prepare();
    pizaa.bake();
    pizaa.cut();
    pizaa.box();
    return pizaa;
    }
    //定义抽象的创建披萨的方法
    abstract Pizaa createPizza(String type);
    }

      3,为了迎合纽约市民的口味,在纽约附近创建一个纽约风味披萨店,即创建一个商店的具体实现类。子类自己去实现获取对象的方法

    package factorymode.factory;
    
    /**
     * @ClassName PrimaryPizzaStrore
     * @Description TODO
     * @Author liuyi
     * @Date 2020/6/16 23:32
     * @Version 1.0
     */
    public class NewYorkPizzaStrore extends PizzaStrore {
        @Override
        Pizaa createPizza(String type) {
            Pizaa pizaa = null;
            switch (type){
                case "cheese":
                    pizaa = new NewYorkCheesePizza();
                    break;
                case "clam":
                    pizaa = new NewYorkClamPizza();
                    break;
            }
            return pizaa;
        }
    }
    

      4,最后我们来看看如何生产一个纽约风味的奶酪披萨。

    package factorymode.factory;
    
    /**
     * @ClassName Test
     * @Description TODO
     * @Author liuyi
     * @Date 2020/6/16 23:34
     * @Version 1.0
     */
    public class Test {
        public static void main(String[] args) {
            //创建一个纽约风味的披萨商店
            PizzaStrore pizzaStrore = new NewYorkPizzaStrore();
            //调用orderPizza方法生产奶酪披萨
            pizzaStrore.orderPizza("cheese");
    //        PizzaStrore pizzaStrore = new PrimaryPizzaStrore();
    //        pizzaStrore.orderPizza("cheese");
        }
    }
    

      

      分析生产披萨的流程,首先定义一个我们需要的风味披萨店,然后生产我们想要的披萨种类。此时我们再来看抽象披萨商店PizzaStrore,

     在orderPizza方法中调用了createPiazza方法去创建披萨,但是我们在进行4个加工步骤的时候其实是不知道具体是什么类型的披萨的,达到了解耦的目的。

    如果我们还要增加一种风味的商店,只需要创建一个类继承PizzaStrore,然后自己去实现创建对应风味的披萨对象的方法,这样我们的购买流程代码基本

    不会改变,只是需要创建对应的商店即可,这样我们的代码就相比于简单工厂更利于扩展,更加灵活。

  • 相关阅读:
    JavaScript对原始数据类型的拆装箱操作
    Javascript继承(原始写法,非es6 class)
    动态作用域与词法作用域
    自行车的保养
    探索JS引擎工作原理 (转)
    C语言提高 (7) 第七天 回调函数 预处理函数DEBUG 动态链接库
    C语言提高 (6) 第六天 文件(续) 链表的操作
    C语言提高 (5) 第五天 结构体,结构体对齐 文件
    C语言提高 (4) 第四天 数组与数组作为参数时的数组指针
    C语言提高 (3) 第三天 二级指针的三种模型 栈上指针数组、栈上二维数组、堆上开辟空间
  • 原文地址:https://www.cnblogs.com/liu-yi/p/13150037.html
Copyright © 2011-2022 走看看