zoukankan      html  css  js  c++  java
  • 设计模式六大原则之工厂方法模式与抽象工厂模式

      前言:不断学习就是程序员的宿命

    一、概述

    案例需求:一个手机的项目:要便于手机种类的扩展,便于维护

      (1)手机的种类很多(比如华为、小米、oppo等)

      (2)手机的制作(prepare,produce,box)

      (3)完成手机店订购的功能

    二、传统模式

    public class OrderPhone {
        // 构造器
        public OrderPhone() {
            Phone phone = null;
            String orderType; // 订购手机的类型
            do {
                orderType = getType();
                if (orderType.equals("xiaomi")) {
                    phone = new XiaomiPhone();
                    phone.setName(" 小米手机 ");
                } else if (orderType.equals("huawei")) {
                    phone = new HuaweiPhone();
                    phone.setName(" 华为手机 ");
                } else if (orderType.equals("pepper")) {
                    phone = new OppoPhone();
                    phone.setName("oppo手机");
                } else {
                    break;
                }
                //输出pizza 制作过程
                phone.prepare();
                phone.produce();
                phone.box();
    
            } while (true);
        }
        // 写一个方法,可以获取客户希望订购的手机种类
        private String getType() {
            try {
                BufferedReader strin = new BufferedReader(new InputStreamReader(System.in));
                System.out.println("input 手机 种类:");
                String str = strin.readLine();
                return str;
            } catch (IOException e) {
                e.printStackTrace();
                return "";
            }
        }
    }
    传统方式

    分析:

      (1)优点:容易理解,简单易操作

      (2)缺点:违反了设计模式的OCP原则(对扩展开放,对修改关闭)当我们给类增加新功能的时候,尽量不修改代码或者尽可能少修改代码

      (3)例如此时要新增加一个手机种类(荣耀手机)则需要新增一个手机类,而且只要是订购手机的代码都要修改

    三、简单工厂模式(违反OCP)

    ①简单工厂模式属于创建型模式,是工厂模式的一种。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。简单工厂模式是工厂模式家族中最简单使用的模式。

    ②简单工厂模式:定义了一个创建对象的类,由这个类来封装实例化对象的行为

    ③在软件开发中,当我们会用到大量的创建某种、某类或某批对象时,就会使用到工厂模式。

      改进:基于传统模式修改,把创建Phone对象封装到一个类中,这样有新的手机类时只需要修改该类即可,其他有创建到Phone对象的代码就不用修改了,改进后的uml类图

    public class SimpleFactory {
        //简单工厂模式 也叫 静态工厂模式
    
        public static Phone createPhone(String orderType) {
    
            Phone phone = null;
    
            System.out.println("使用简单工厂模式");
            if (orderType.equals("xiaomi")) {
                phone = new XiaomiPhone();
                phone.setName(" 小米手机 ");
            } else if (orderType.equals("huawei")) {
                phone = new HuaweiPhone();
                phone.setName(" 华为手机 ");
            } else if (orderType.equals("pepper")) {
                phone = new OppoPhone();
                phone.setName("oppo手机");
            }
    
            return phone;
        }
    }
    View Code

    三、工厂方法模式 

    1、工厂方法模式4要素

      ①抽象工厂(Abstract Factory):提供了创建产品的接口,调用者通过它访问具体工厂的工厂方法new Product()来创建产品。

      ②具体工厂(ConcreteFactory):主要是实现抽象工厂中的抽象方法,完成具体产品的创建。

      ③抽象产品(Product):定义了产品的规范,描述了产品的主要特性和功能。

      ④具体产品(ConcreteProduct):实现了抽象产品角色所定义的接口,由具体工厂来创建,它同具体工厂之间一一对应。

    2、新需求

      客户在订购手机时,可以选择不同颜色的手机,比如小米梦幻蓝Phone、小米曜石黑Phone或者华为零度白Phone、华为亮黑色Phone。

      思路1:使用工厂模式,创建不同的简单工厂类,比如XMBlueSimpleFactory、HWBlackSimpleFactory等,这样考虑是可以的,但是考虑到项目的规模,以及软件的可维护性、可扩展性并不是特别好。

      思路2:使用工厂方法模式

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

      基于工厂方法模式设计方案:将手机实例化功能抽象成抽象方法,在不同颜色的订购子类中具体实现。

    分析:

      (1)优点

        ①用户只需要知道具体工厂的名称就可得到所要的产品,无须知道产品的具体创建过程;

        ②在系统增加新的产品时只需要添加具体产品类和对应的具体工厂类,无须对原工厂进行任何修改,满足开闭原则;

      (2)缺点:每增加一个产品就要增加一个具体产品类和一个对应的具体工厂类,这增加了系统的复杂度。

    3、适用场景

    (1)客户只知道创建产品的工厂名,而不知道具体的产品名。如 TCL 电视工厂、海信电视工厂等。

    (2)创建对象的任务由多个具体子工厂中的某一个完成,而抽象工厂只提供创建产品的接口。

    (3)客户不关心创建产品的细节,只关心产品的品牌。

    四、抽象工厂模式

    1、简介

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

    2、模式结构

    ①抽象工厂(Abstract Factory):提供了创建产品的接口,它包含多个创建产品的方法 newProduct(),可以创建多个不同等级的产品。

    ②具体工厂(Concrete Factory):主要是实现抽象工厂中的多个抽象方法,完成具体产品的创建。

    ③抽象产品(Product):定义了产品的规范,描述了产品的主要特性和功能,抽象工厂模式有多个抽象产品。

    ④具体产品(ConcreteProduct):实现了抽象产品角色所定义的接口,由具体工厂来创建,它 同具体工厂之间是多对一的关系。

    3、本例UML类图

     分析:

      (1)当增加一个新的产品族(Oppo手机类)时只需增加一个新的具体工厂(Oppo工厂),不需要修改原代码,满足开闭原则

      (2)当产品族中需要增加一个新种类(抽象工厂新增生产空调产品)的产品时,则所有的工厂类(各个具体工厂例如华为、小米工厂类等都要修改)都需要进行修改,不满足开闭原则

     4、适用场景

    (1)当需要创建的对象是一系列相互关联或相互依赖的产品族时,如电器工厂中的电视机、洗衣机、空调等。

    (2)系统中有多个产品族,但每次只使用其中的某一族产品。如有人只喜欢穿某一个品牌的衣服和鞋。

    (3)系统中提供了产品的类库,且所有产品的接口相同,客户端不依赖产品实例的创建细节和内部结构。

    五、工厂模式在JDK源码中的应用

     六、总结

    1、工厂模式的意义:将实例化对象的代码提取出来,放到一个类中统一管理维护,达到和主项目依赖关系的管理,从而提高项目的扩展和维护性。

    2、设计模式的依赖抽象原则:

      ①创建对象实例时,不要直接new类,而是把这个new类的动作放在一个工厂的方法中并返回(变量不要直接持有具体类的引用)

      ②不要让类继承具体类,而是继承抽象类或是实现Interface接口

      ③不要覆盖基类中已实现的方法

     参考:http://c.biancheng.net/view/1351.html(如有侵权,请联系删除)

  • 相关阅读:
    hi.baidu.com 百度流量统计
    Autofac is designed to track and dispose of resources for you.
    IIS Manager could not load type for module provider 'SharedConfig' that is declared in administration.config
    How to create and manage configuration backups in Internet Information Services 7.0
    定制swagger的UI
    NSwag在asp.net web api中的使用,基于Global.asax
    NSwag Tutorial: Integrate the NSwag toolchain into your ASP.NET Web API project
    JS变量对象详解
    JS执行上下文(执行环境)详细图解
    JS内存空间详细图解
  • 原文地址:https://www.cnblogs.com/rmxd/p/12635635.html
Copyright © 2011-2022 走看看