zoukankan      html  css  js  c++  java
  • 设计模式(工厂模式)

    一、 简介

    工厂方法模式是一种 创建模式,该模式使用工厂方法来处理创建对象的问题,而不必指定将要创建的对象的确切类。这是通过调用工厂方法(而不是通过构造函数)来创建对象的,该工厂方法是在接口中指定并由子类实现,或者在基类中实现,并且可以选择由派生类覆盖。

     

    二、工作模式的N种方式

    我们从一个简单的披萨项目入手,项目需要满足三个需求:

    a、披萨的种类很多(比如 GreekPizz、CheesePizz 等) b、披萨的制作有 prepare,bake, cut, box c、完成披萨店订购功能

    1、原始方法

    类图

     

    案例

    1、定义一个抽象类,完成披萨的制作过程

    package com.ycdhz.design.factory.simplefactory;
    
    public abstract class Pizza {
    
        private String pizzaType;
    
        public abstract void prepare();
    
        public void bake() {
            System.out.println("bake");
        }
    
        public void cut() {
            System.out.println("cut");
        }
    
        public void box() {
            System.out.println("box");
        }
    
        public void setPizzaType(String pizzaType) {
            this.pizzaType = pizzaType;
        }
    }

    2、不同的Pizza 类型去继承Pizza 的抽象类

    package com.ycdhz.design.factory.simplefactory;
    
    public class CheesePizza extends Pizza {
    
        @Override
        public void prepare() {
            System.out.println("制作奶酪披萨的原材料");
        }
    }
    
    public class ChickenPizza extends Pizza {
    
        @Override
        public void prepare() {
            System.out.println("制作鸡肉披萨的原材料");
        }
    }

    3、定制一个类,来专门的定制Pizza

    package com.ycdhz.design.factory.simplefactory;
    
    public class OrderPizza {
    
        public void getOrderPizza(String type){
            Pizza pizza = null;
    
            if(type.equals("cheese")){
                pizza = new CheesePizza();
                pizza.setPizzaType(type);
            } else if (type.equals("chicken")){
                pizza = new ChickenPizza();
                pizza.setPizzaType(type);
            } else {
                System.out.println(type + "以售尽");
            }
    
            pizza.prepare();
            pizza.bake();
            pizza.cut();
            pizza.box();
        }
    }

    4、 模拟一个客户端,例如 开一个新的Pizza 店,调用OrderPizza

    package com.ycdhz.design.factory.simplefactory;
    
    public class PizzaStore {
    
        public static void main(String[] args) {
            OrderPizza orderPizza = new OrderPizza();
            orderPizza.getOrderPizza("cheese");
        }
    }

    2、简单工厂

    每一个Pizza 店铺,都可能有一个对应的OrderPizza 类,如果说我们更新了Pizza 的类型,必然会对所有的OrderPizza 类进行一个修改。 我们可以把创建 Pizza 对象封装到一个类中,这样我们有新的 Pizza 种类时只需要修改该类就可,其它有创建到 Pizza 对象的代码就不需要修改了。

    类图

     

    案例

    1、 从OrderPizza 中将createPizza 提取出来,形成SimplePizzaFactory

    package com.ycdhz.design.factory.simplefactory;
    
    public class SimplePizzaFactory {
    
        public Pizza createPizza(String type){
            Pizza pizza = null;
    
            if(type.equals("cheese")){
                pizza = new CheesePizza();
            } else if (type.equals("chicken")) {
                pizza = new ChickenPizza();
            } else {
                return pizza;
            }
            return pizza;
        }
    }

     2、 定制Pizza 过程,通过构造方法来实例化 SimplePizzaFactory

    package com.ycdhz.design.factory.simplefactory;
    
    public class OrderPizza {
    
        SimplePizzaFactory simpleFactory;
    
        public OrderPizza(SimplePizzaFactory simpleFactory) {
            this.pizzaType = pizzaType;
        }
    
        public void orderPizza(String type) {
    
            Pizza pizza = this.simpleFactory.createPizza(type);
    
            if(pizza != null) {
                pizza.prepare();
                pizza.bake();
                pizza.cut();
                pizza.box();
            } else {
                System.out.println(" 订购披萨失败 ");
            }
        }
    }

    3、模拟一个客户端,调用OrderPizza

    package com.ycdhz.design.factory.simplefactory;
    
    public class PizzaStore {
    
        public static void main(String[] args) {
            OrderPizza pizzaStore = new OrderPizza(new SimplePizzaFactory());
            pizzaStore.orderPizza("cheese");
        }
    }

    总结:简单工厂模式是属于 创建型模式,是工厂模式的一种。简单工厂模式是由一个工厂对象决定创建出哪一种产品 类的实例。

    3、工厂方法

    随着用户数量的增加,客户群体也在不断的变换。客户对披萨口味有更多的要求,比如北京的奶酪 pizza、北京的胡椒 pizza 或者是伦敦的奶酪 pizza、伦敦的胡椒 pizza。如果是简单工厂方式,我们可以通过新增ZHSimplePizzaFactory、NYSimplePizzaFactory 来进行解决。但考虑到项目的可维护性,我们可以将项目中实例化功能抽象成抽象方法,放到子类中去完成。

    类图

    案例

    1、 修改OrderPizza 类, 将createPizza 交给子类来完成

    public abstract class OrderPizza {
    
        public void orderPizza (String type){
            Pizza pizza = createPizza(type);
    
            pizza.prepare();
            pizza.bake();
            pizza.cut();
            pizza.box();
        }
    
        public abstract Pizza createPizza(String type);
    }

    2、定义一个ZHOrderPizza 来完成中国口味的pizza 的

    public class ZHOrderPizza extends OrderPizza {
    
        @Override
        public Pizza createPizza(String type) {
            Pizza pizza = null;
            if(type.equals("cheese")){
                pizza = new ZHCheesePizza();
            } else if (type.equals("chicken")) {
                pizza = new ZHChickenPizza();
            } else {
                System.out.println("not pizza");
            }
            return pizza;
        }
    }

    3、模拟一个客户端,调用OrderPizza

    public class PizzaStore {
    
        public static void main(String[] args) {
            OrderPizza pizzaStore = new ZHOrderPizza();
            pizzaStore.orderPizza("cheese");
        }
    }

    总结:定义了一个创建对象的抽象方法,由子类决定要实例化的类。工厂方法模式将对象的实例化推迟到子类。

    4、抽象工厂

    随着加盟店铺的增加,我们需要对pizza 的原料进行统一处理。 这个时候我们需要为每个区域建造一个工厂并继承自PizzaIngredientFactory。同时要实现一组原料类供工厂使用。

    类图

    案例

    1、 创建一组原料类

    public class Dough {}
    
    public class Sauce {}

    2、 创建一个原料接口

    public interface PizzaIngredientFactory {
    
        public Dough createDough();
    
        public Sauce createSauce();
    }

    3、创建一个纽约的原材料类实现原料接口

    package com.ycdhz.design.factory.factorydesign;
    
    public class NYPizzaIngredientFactory implements PizzaIngredientFactory {
    
        @Override
        public Dough createDough() {
            System.out.println("NY pizza Dough");
            return null;
        }
    
        @Override
        public Sauce createSauce() {
            System.out.println("NY pizza Sauce");
            return null;
        }
    }

    4、 创建一个Pizza 类

    public abstract class Pizza {
    
        public Dough dough;
    
        public Sauce sauce;
    
        protected abstract void prepare();
    
        public void bake() {
            System.out.println("bake");
        }
    
        public void cut() {
            System.out.println("cut");
        }
    
        public void box() {
            System.out.println("box");
        }
    
        public Dough getDough() {
            return dough;
        }
    
        public void setDough(Dough dough) {
            this.dough = dough;
        }
    
        public Sauce getSauce() {
            return sauce;
        }
    
        public void setSauce(Sauce sauce) {
            this.sauce = sauce;
        }
    }

    5、根据不同种类的Pizza 去继承Pizza 类

    public class CheesePizza extends Pizza {
    
        PizzaIngredientFactory ingredientFactory;
    
        public CheesePizza(PizzaIngredientFactory ingredientFactory){
            this.ingredientFactory = ingredientFactory;
        }
    
        @Override
        public void prepare() {
            this.dough = ingredientFactory.createDough();
            this.sauce = ingredientFactory.createSauce();
        }
    }

    6、 通过OrderPizza 进行组装

    public abstract class OrderPizza {
    
        protected Pizza orderPizza(String type){
            Pizza pizza = createPizza(type);
    
            pizza.prepare();
            pizza.bake();
            pizza.cut();
            pizza.box();
            return pizza;
        }
    
        protected abstract Pizza createPizza(String type);
    }
    public class NYOrderPizza extends OrderPizza {
    
        @Override
        protected Pizza createPizza(String type) {
            Pizza pizza = null;
            PizzaIngredientFactory factory = new NYPizzaIngredientFactory();
    
            if(type.equals("cheese")){
                pizza = new CheesePizza(factory);
            } else if (type.equals("chicken")) {
                pizza = new ChickenPizza(factory);
            } else {
                System.out.println("没有当前品种的pizza");
                return null;
            }
    
            return pizza;
        }
    }

    4、模拟一个客户端,调用OrderPizza

    public class PizzaStore {
    
        public static void main(String[] args) {
            OrderPizza pizzaStore = new NYOrderPizza();
            pizzaStore.orderPizza("cheese");
        }
    }

    总结:抽象工厂模式:定义了一个 interface 用于创建相关或有依赖关系的对象簇,而无需指明具体的类。从设计层面看,抽象工厂模式就是对简单工厂模式的改进(或者称为进一步的抽象)。将工厂抽象成两层,OrderPizza( 抽象工厂) 和 具体实现的工厂子类。程序员可以根据创建对象类型使用对应的工厂子类。这样将单个的简单工厂类变成了工厂簇,更利于代码的维护和扩展。

  • 相关阅读:
    2016 大连网赛
    LightOJ 1012 简单bfs,水
    Pyhton学习——Day30
    Client初见——python
    Server初见——python
    Pyhton学习——Day29
    Pyhton学习——Day28
    Pyhton学习——Day27
    Pyhton学习——Day26
    函数基础作业
  • 原文地址:https://www.cnblogs.com/jiangyaxiong1990/p/13467973.html
Copyright © 2011-2022 走看看