zoukankan      html  css  js  c++  java
  • 设计模式总结:创建型模式

    创建型模式

    • 类模式
      • 工厂方法模式
    • 对象模式
      • 抽象工厂模式
      • 建造者模式
      • 原型模式
      • 单例模式
    1. 单例(Singleton)模式:某个类只能生成一个实例,该类提供了一个全局访问点供外部获取该实例,其拓展是有限多例模式。
    2. 原型(Prototype)模式:将一个对象作为原型,通过对其进行复制而克隆出多个和原型类似的新实例。
    3. 工厂方法(FactoryMethod)模式:定义一个用于创建产品的接口,由子类决定生产什么产品。
    4. 抽象工厂(AbstractFactory)模式:提供一个创建产品族的接口,其每个子类可以生产一系列相关的产品。
    5. 建造者(Builder)模式:将一个复杂对象分解成多个相对简单的部分,然后根据不同需要分别创建它们,最后构建成该复杂对象。

    1 简单工厂模式 Simple Factory

    image-20210623151455241

    1.1 定义

    • 简单工厂模式(Simple Factory Pattern),又称为静态工厂方法(Static Factory Method)模式
    • 根据参数的不同返回不同类的实例
    • 专门定义一个类来负责创建其他类的实例,被创建的实例通常具有共同的父类

    包含如下角色

    • Factory 工厂角色
    • Product 抽象产品角色
    • ConcreteProduct 具体产品角色

    1.2 模式分析

    • 对象的创建对象本身业务处理分离可以降低系统的耦合度 ,使得两者修改起来都相对容易。

    • 简单工厂模式的要点在于:当你需要什么,只需要传入一个正确的参数,就可以获取你所需要的对象,而无须知道其创建细节。

    • 优点

      • 实现了对责任的分割,提供专门的工厂类用于创建对象
      • 客户端无需知道所创建的具体产品类目,只需要知道产品类对应的参数即可
      • 引入配置文件,可以在不修改客户端代码的情况下更换和新增新的具体产品类
    • 缺点

      • 工厂类集合了所有产品创建逻辑,一旦不能工作,整个系统都会被影响
      • 会增加类的个数
      • 拓展困难,一旦添加新产品,就不得不修改工厂逻辑(违背了开闭原则)
    • 适用

      • 工厂类负责创建的对象比较少(不会导致工厂的逻辑太复杂)
      • 客户端只知道传入工厂类的参数,对于如何创建对象不关心
    • 简化

      • 可以把静态工厂方法写到抽象产品类中

        image-20210623154138187

    1.3 例子

    • 根据不同的权限等级创建不同的用户对象,不同的用户对象拥有不同的操作权限

      image-20210623153554085

    • JDK日期格式化类

      image-20210623154017832

    • JDK加密技术

      image-20210623154029743

    2 工厂方法模式 Factory Method

    image-20210623154408591

    2.1 模式动机

    考虑简单工厂的不足,即要增加新产品时,除了增加一个新的具体产品类之外,还需要修改工厂类的代码,这就使得整个设计在一定程度上违反了“开闭原则 ”

    修改:不再设计一个工厂类来统一负责所有产品的创建,而是将具体类的创建过程交给专门的工厂子类去完成

    2.2 定义

    • 工厂方法模式(Factory Method Pattern)又称为工厂模式,也叫虚拟构造器(Virtual Constructor)模式或者多态工厂(Polymorphic Factory)模式

    2.3 模式分析

    • 在工厂方法模式中,核心的工厂类不再负责所有产 品的创建,而是将具体创建工作交给子类去做。因此,工厂方法模式可以允许系统在不修改工厂角色的情况下引进新产品(符合开闭原则)

    • 在定义工厂和产品时都必须使用抽象层,如果需要更换产品类,只需要更换对应的工厂即可,其他代 码不需要进行任何修改。

      image-20210623154841377

    • 优点

      • 用户只需关心所需产品对应的工厂,无需关心创建细节,甚至无需知道具体产品类名
      • 工厂可以自主确定如何创建何种产品对象,如何创建对象的细节完全封装在工厂内部
      • 引入新产品时,无需修改抽象工厂和产品,无需修改客户端,也无需修改其他具体工厂和产品,只需要添加一个具体产品和工厂类即可
    • 缺点

      • 引入新产品时,需要引入具体工厂类,一定程度上增加了系统的复杂度
      • 客户端中需要使用对抽象层的定义,增加系统的抽象性和理解难度,需要用到反射等技术
    • 适用

      • 一个类不知道它所需要的对象的类
      • 一个类通过其子类来指定创建哪个对象
      • 将创建对象的任务委托给多个工厂子类中的一个,在使用时动态指定

    2.4 例子

    image-20210623154929931

    3 抽象工厂模式 Abstract Factory

    image-20210623155951981

    3.1 模式动机

    • 工厂方法中,一个具体工厂对应一种具体产品
    • 有时候我们为需要一个工厂可以提供多个产品对象,而不是单一的产品对象

    3.2 定义

    • 抽象工厂模式(Abstract Factory Pattern):提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类。抽象工厂模式又称为Kit模式,属于对象创建型模式

    引入两个概念

    • 产品等级结构:即产品的继承结构,如抽象电视机是父类,具体品牌的电视机是其子类
    • 产品族:指由同一个工厂生产的,位于不同产品等级结构中的一组产品

    包含以下角色:

    • AbstractFactory
    • ConcreteFactory
    • AbstractProduct
    • Product

    3.3 模式分析

    • 优点

      • 隔离了具体类的生成,使得客户端不需要知道什么被创建
      • 所有的具体工厂都实现了抽象工厂中的公共接口,只需要替换具体工厂,就可以改变整个软件系统的行为
      • 高内聚、低耦合
      • 保证客户端始终使用同一个产品族的对象
      • 增加新的具体工厂和产品族很方便,无需修改已有系统(开闭原则)
    • 缺点

      • 添加新的产品时,很难扩展抽象工厂来生成新的产品
      • 新增新的产品族和工厂容易,新增新的产品等级结构难。即开闭原则的倾斜性
    • 适用

      • 一个系统不应当依赖产品类实例如何被创建、组合和表达的细节(对所有工厂模式都很重要)
      • 系统中有多个产品族,且每次只用一个
      • 属于同一个产品族的产品将在一起使用
      • 系统提供一个产品族的库,所有的产品以同样的接口出现,从而使客户端不依赖于具体实现

    3.4 例子

    • 一个电器工厂可以生产多个类型的电器,有多个工厂

      image-20210623160133960

    • 针对不同的数据库,提供Connector和Statement

      image-20210623160228470

    4 工厂模式退化

    image-20210623160840317

    5 建造者模式 Builder

    建造者模式(Bulider模式)详解 (biancheng.net)

    image-20210623161621431

    5.1 模式动机

    • 存在一些复杂的对象,有多个组成部分,如汽车包括轮胎、方向盘等,而对于大多数用户而言,无须知道这些部件的装配细节,也几乎不会使用单独某个部件,而是使用一辆完整的汽车
    • 建造者模式可以将部件和其组装过程分开,一步一步创建一个复杂的对象
    • 建造者返还给客户端的是一个已经建造完毕的完整产品对象,而用户无须关心该对象所包含的属性以及它们的组装方式。

    5.2 定义

    • 建造者模式(Builder Pattern):将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

    包含以下角色

    • Builder:抽象建造者
    • ConcreteBuilder:具体建造者
    • Director:指挥者
    • Product:产品角色

    5.3 模式分析

    • 引入指挥者类,一方面它隔离了客户与生产过 程;另一方面它负责控制产品的生成过程。

      image-20210623161840443

    • 在客户端代码中,无需关心产品对象的具体组装过程,只需确定具体的建造者类型即可

      image-20210623161955295

    • 优点

      • 客户端不必知道产品内部组成的细节,将产品本身与产品的创建过程解耦,使得相同的创建过程可以创建不同的产品对象。
      • 每一个具体建造者都相对独立,而与其他的具体建造者无关,用户使用不同的具体建造者即可得到不同的产品对象。
      • 可以更加精细地控制产品的创建过程。
      • 增加新的具体建造者无须修改原有类库的代码,指挥者类针对抽象建造者类编程,系统扩展方便,符合“开闭原则”。
    • 缺点

      • 如果产品之间的差异性很大,则不适合使用建造者模式,因此其使用范围受到一定的限制。
      • 如果产品的内部变化复杂,可能会导致需要定义很多具体建造者类来实现这种变化,导致系统变得很庞大
    • 适用

      • 需要生成的产品对象有复杂的内部结构,这些产品对象通常包含多个成员属性。
      • 需要生成的产品对象的属性相互依赖,需要指定其生成顺序。
      • 对象的创建过程独立于创建该对象的类。在建造者模式中引入了指挥者类,将创建过程封装在指挥者类中,而不在建造者类中。
      • 隔离复杂对象的创建和使用,并使得相同的创建过程可以创建不同的产品
    • 简化

      • 省略抽象建造者角色:如果系统中只需要一个具体建造 者的话,可以省略掉抽象建造者。
      • 省略指挥者角色:在具体建造者只有一个的情况下,如 果抽象建造者角色已经被省略掉,那么还可以省略指挥 者角色,让Builder角色扮演指挥者与建造者双重角色。

    5.4 例子

    建造者模式可以用于描述KFC如何创建套餐:套餐是一个复杂对象,它一般包含主食(如汉堡、鸡肉卷等)和 饮料(如果汁、可乐等)等组成部分,不同的套餐有不同的组成部分,而KFC的服务员可以根据顾客的要求, 一步一步装配这些组成部分,构造一份完整的套餐,然后返回给顾客

    image-20210623163044297

    5.5 对比

    通过前面的学习,我们已经了解了建造者模式,那么它和工厂模式有什么区别呢?

    • 建造者模式更加注重方法的调用顺序,工厂模式注重创建对象。
    • 创建对象的力度不同,建造者模式创建复杂的对象,由各种复杂的部件组成,工厂模式创建出来的对象都一样
    • 关注重点不一样,工厂模式只需要把对象创建出来就可以了,而建造者模式不仅要创建出对象,还要知道对象由哪些部件组成。
    • 建造者模式根据建造过程中的顺序不一样,最终对象部件组成也不一样。

    6 原型模式 Prototype

    image-20210623163926535

    6.1 模式动机

    • 使用原型模式来复制一个对象自身, 从而克隆出多个与原型对象一模一样的对象
    • 在软件系统中,有些对象的创建过程较为复杂,而且有时候需要频繁创建,原型模式通过给出一个原型对象来指明 所要创建的对象的类型,然后用复制这个原型对象的办法创建出更多同类型的对象,这就是原型模式的意图所在。

    6.2 定义

    • 原型模式(Prototype Pattern):原型模式是一种对象创建型模式,用原型实例指定创建对象的种类,并且通过复 制这些原型创建新的对象。

    • 原型模式允许一个对象再创建另外一个可定制的对象,无须知道任何创建的细节。

    原型模式包含如下角色:

    • Prototype:抽象原型类
    • ConcretePrototype:具体原型类
    • Client:客户类

    6.3 模式分析

    • 一个类包含一些成员对象,在使用原型模式克隆对象时,根据其成员对象是否也克隆,原型模式可以分为两种形式:深克隆和浅克隆

    • JAVA中有clone方法

      • 所有的Java 类都继承自java.lang.Object,而Object类提供一个 clone()方法,可以将一个Java对象复制一份
      • 能够实现克隆的Java类必须实现一个标识接口Cloneable, 表示这个Java类支持复制。如果一个类没有实现这个接 口但是调用了clone()方法,Java编译器将抛出一个 CloneNotSupportedException异常。
      • 对任何的对象x,都有x.clone()!=x,即克隆对象与 原对象不是同一个对象。
      • 对任何的对象x,都有 x.clone().getClass()==x.getClass(),即克隆对象与原 对象的类型一样。
      • 如果对象x的equals()方法定义恰当,那么 x.clone().equals(x)应该成立。
    • 优点

      • 使用原型模式可以简化对象的创建过程,通过一个已有实例可以提高新实例 的创建效率。
      • 可以动态增加或减少产品类。
      • 原型模式提供了简化的创建结构。
      • 可以使用深克隆的方式保存对象的状态
    • 缺点

      • 需要为每一个类配备一个克隆方法,对已有的类进行改造时,不一定是件容易的事, 必须修改其源代码,违背了“开闭原则”。
      • 在实现深克隆时需要编写较为复杂的代码
    • 适用

      • 创建新对象成本较大
      • 如果系统要保存对象的状态,而对象的状态变化很小,或者对象本身占内存不大的时候
      • 需要避免使用分层次的工厂类来创建分层次的对象,并且类的实例对象只有一个或很少的几个组合状态,通过复制原型对象 得到新实例可能比使用构造函数创建一个新实例更加方便
    • 扩展

      • 原型管理器原型模式(原型设计模式)详解 (biancheng.net)

        image-20210623172117692

      • 相似对象的复制

        很多情况下,复制所得到的对象与原型对象并不是完全相同的,它们的某些属性值存在异同。通过原型模式获 得相同对象后可以再对其属性进行修改,从而获取所需对象。

    6.4 例子

    • 原型模式应用于很多软件中,如果每次创建一个对象要花大量时间,原型模式是最好的解决方案。很多软件提 供的复制(Ctrl + C)和粘贴(Ctrl + V)操作就是原型模式的应用
    • 在Spring中,用户也可以采用原型模式来创建新的bean实例,从而实现每次获取的是通过克隆生成的新实例,对其进行修改时对原有实例对象不造成任何影响。
  • 相关阅读:
    我们为什么要使用Spring Cloud?简介
    Spring注解@Component、@Repository、@Service、@Controller区别
    Spring boot 各种入门及问题
    spring boot与spring mvc的区别是什么?
    Android http Request / Response ContentType
    Android Studio添加aar
    Android 自定义线程池的实战
    Android AsyncTask 深度理解、简单封装、任务队列分析、自定义线程池
    EditText 显示明文和密码
    Android log 管理工具
  • 原文地址:https://www.cnblogs.com/cpaulyz/p/14923697.html
Copyright © 2011-2022 走看看