【学习笔记】软件设计模式(二)创建型模式

软件设计模式之创建型模式

本人学习笔记。内容参考《Java设计模式》刘伟 教程配套PPT。仅供学习参考使用。

总述

创建型模式关注对象的创建过程。对类的实例化过程进行了抽象,能够将软件模块中对象的创建和对象的使用分离,对用户隐藏了类的实例的创建细节。

创建型模式描述如何将对象的创建和使用分离,让用户在使用对象时无须关心对象的创建细节,从而降低系统的耦合度,让设计方案更易于修改和扩展。

创建型模式有6种,下面的表格我总结了它们的定义和例子:

模式名称 定义 形象化例子 应用实例
简单工厂模式 定义一个工厂类,它可以根据参数的不同返回不同类的实例,被创建的实例通常都具有共同的父类。 农场种瓜得瓜 提供多种不同外观的图表的图表库
工厂方法模式 定义一个用于创建对象的接口,但是让子类决定将哪一个类实例化。工厂方法模式让一个类的实例化延迟到其子类。 一个工厂生产一样产品 通过多种途径保存日志的日志记录器
抽象工厂模式 提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类。 一个工厂生产一种风格的系列产品 提供不同风格界面的皮肤库
建造者模式 将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。 生产汽车不用管零部件 有多个属性的游戏角色
原型模式 使用原型实例指定待创建对象的类型,并且通过复制这个原型来创建新的对象。 孙悟空拔毛 快速创建相同或者相似的周报
单例模式 确保一个类只有一个实例,并提供一个全局访问点来访问这个唯一实例。 Windows任务管理器 负责管理和请求的分发的服务器负载均衡器

1.简单工厂模式

概述

定义一个工厂类,它可以根据参数的不同返回不同类的实例,被创建的实例通常都具有共同的父类。
如果需要什么,只需要传入一个正确的参数,就可以获取所需要的对象,而无须知道其创建细节。

结构

客户端需要产品A,则告知工厂并获得抽象产品,工厂生产具体的产品A而返回。
在这里插入图片描述

优缺点

优点:

  • 实现了对象创建和使用的分离。
  • 客户端无须知道所创建的具体产品类的类名,只需要知道具体产品类所对应的参数即可。
  • 通过引入配置文件,可以在不修改任何客户端代码的情况下更换和增加新的具体产品类,在一定程度上提高了系统的灵活性。

缺点:

  • 工厂类集中了所有产品的创建逻辑,一旦不能正常工作,整个系统都要受到影响。
  • 增加系统中类的个数(引入了新的工厂类),增加了系统的复杂度和理解难度。
  • 不满足开闭原则。系统扩展困难,一旦添加新产品不得不修改工厂逻辑。
  • 由于使用了静态工厂方法,造成工厂角色无法形成基于继承的等级结构,工厂类不能得到很好地扩展。

2.工厂方法模式

概述

定义一个用于创建对象的接口,但是让子类决定将哪一个类实例化。工厂方法模式让一个类的实例化延迟到其子类。
工厂父类负责定义创建产品对象的公共接口,而工厂子类则负责生成具体的产品对象。目的是将产品类的实例化操作延迟到工厂子类中完成,即通过工厂子类来确定究竟应该实例化哪一个具体产品类。

结构

客户端需要产品A,则告知抽象工厂并获得抽象产品,抽象工厂告知A具体工厂,A具体工厂生产具体的产品A而返回。注意,抽象工厂、抽象产品是接口(或父类)。
在这里插入图片描述

优缺点

优点:

  • 工厂方法用来创建客户所需要的产品,同时还向客户隐藏了哪种具体产品类将被实例化这一细节。能够让工厂自主确定创建何种产品对象,而如何创建这个对象的细节则完全封装在具体工厂内部。
  • 在系统中加入新产品时,完全符合开闭原则

缺点:

  • 系统中类的个数将成对增加,在一定程度上增加了系统的复杂度,会给系统带来一些额外的开销。增加了系统的抽象性和理解难度。

3.抽象工厂模式

概述

提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类。

抽象工厂模式中的具体工厂不只是创建一种产品,它负责创建一族产品。当一个工厂等级结构可以创建出分属于不同产品等级结构的一个产品族中的所有对象时,抽象工厂模式比工厂方法模式更为简单、更有效率(工程方法每个具体工厂只有一个或者一组重载的工厂方法,只能生产一种产品)。

经典例子:皮肤库,有不同的皮肤,每种皮肤有相同风格的多个元件。(不同皮肤元件种类相同)

结构

客户需要风格A的一组产品,那么从抽象工厂获得一系列抽象产品,抽象工厂让具体工厂A生成A风格的一系列产品而返回。
在这里插入图片描述

优缺点

优点:

  • 隔离了具体类的生成,使得客户端并不需要知道什么被创建。
  • 当一个产品族中的多个对象被设计成一起工作时,它能够保证客户端始终只使用同一个产品族中的对象。
  • 增加新的产品族(风格)很方便,无须修改已有系统,符合开闭原则

缺点:

  • 增加新的产品等级结构(组件)麻烦,需要对原有系统进行较大的修改,甚至需要修改抽象层代码,违背开闭原则

4.建造者模式

概述

将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

建造者模式可以将部件本身和它们的组装过程分开,关注如何一步步创建一个包含多个组成部分的复杂对象,客户端无须知道复杂对象的内部组成部分与装配方式,只需要知道所需建造者的类型即可。

经典例子:建造有多个组成部分且不同产品组成部分一样的复杂产品,如汽车、游戏角色。

结构

客户端让抽象建造者建造产品A,抽象建造者让具体建造者A建造不同的部分,组成产品A而返回。
在这里插入图片描述

优缺点

优点:

  • 客户端不必知道产品内部组成的细节,将产品本身与产品的创建过程解耦,使得相同的创建过程可以创建不同的产品对象。
  • 每一个具体建造者都相对独立,与其他的具体建造者无关,因此可以很方便地替换具体建造者或增加新的具体建造者,扩展方便,符合开闭原则
  • 可以更加精细地控制产品的创建过程。

缺点:

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

5.原型模式

概述

使用原型实例指定待创建对象的类型,并且通过复制这个原型来创建新的对象。

要发动创建的对象通过请求原型对象复制后者自己来实现创建过程。创建克隆对象的工厂就是原型类自身,工厂方法由负责复制原型对象的克隆方法来实现。通过克隆方法所创建的对象是全新、独立的对象,它们在内存中拥有新的地址。通过不同的方式对克隆对象进行修改以后,可以得到一系列相似但不完全相同的对象。

克隆分浅克隆和深克隆,区别在对象包含的成员变量是否被复制(复制地址或新建)。
可增加一个原型管理器,将多个原型对象存储在一个集合中供客户端使用。

结构

将一个原型对象传给客户端对象,客户端对象通过请求原型对象复制自己来实现创建过程。

在这里插入图片描述

优缺点

优点:

  • 简化对象的创建过程,通过复制一个已有实例可以提高新实例的创建效率。
  • 扩展性较好。
  • 提供了简化的创建结构,无须专门的工厂类来创建产品。
  • 可以使用深克隆的方式保存对象的状态,需要的时候可辅助实现撤销操作。

缺点:

  • 需要为每一个类配备一个克隆方法,而且该克隆方法位于一个类的内部,当对已有的类进行改造时,需要修改源代码,违背了开闭原则
  • 在实现深克隆时需要编写较为复杂的代码。

6.单例模式

概述

确保一个类只有一个实例,并提供一个全局访问点来访问这个唯一实例。

某个类只能有一个实例。必须自行创建这个实例。必须自行向整个系统提供这个实例。

经典例子:任务管理器、回收站。

结构

单例模式只包含一个单例角色。聚合自己。

饿汉式单例模式
无须考虑多个线程同时访问的问题;调用速度和反应时间优于懒汉式单例;资源利用效率不及懒汉式单例;系统加载时间可能会比较长。

在这里插入图片描述

public class EagerSingleton { 
    private static final EagerSingleton instance = new EagerSingleton(); 
    private EagerSingleton() { } 
 
    public static EagerSingleton getInstance() {
        return instance; 
    }
}

懒汉式单例模式
实现了延迟加载;必须处理好多个线程同时访问的问题;需通过双重检查锁定等机制进行控制,将导致系统性能受到一定影响。
在这里插入图片描述

public class LazySingleton { 
    private volatile static LazySingleton instance = null; 

    private LazySingleton() { } 

    public static LazySingleton getInstance() { 
        //第一重判断
        if (instance == null) {
            //锁定代码块
            synchronized (LazySingleton.class) {
                //第二重判断
                if (instance == null) {
                    instance = new LazySingleton(); //创建单例实例
                }
            }
        }
    return instance; 
    }
}

优缺点

优点:

  • 提供了对唯一实例的受控访问。
  • 可以节约系统资源,提高系统的性能。

缺点:

  • 缺少抽象层,扩展困难。
  • 例类的职责过重。
  • 由于自动垃圾回收机制,可能会导致共享的单例对象的状态丢失。

练习

分别用简单工厂模式、工厂方法模式、抽象工厂模式、建造者模式设计一个简单的画图板(绘制直线、长方形、圆等),每个要求类似,每个都体现了这种模式的功能。(未完待续)

UML图如下:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

发布了10 篇原创文章 · 获赞 14 · 访问量 648

猜你喜欢

转载自blog.csdn.net/weixin_42368748/article/details/103512843