设计模式 - 创建型模式 | 青训营笔记

63 阅读6分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 19 天

创建型模式

  • 将对象的创建过程和使用过程进行分离
  • 创建型模式更加关注对象的创建过程
  • 创建型模式,更加符合单一职责,外界只需要知道他们的共同接口即可

简单工厂模式

别名:静态工厂方法模式

问题:只需要某个参数,就可以获得相应的对象,这个工厂方法定义为 static 类型。

定义:根据不同的参数获取不同类的实例,这些不同的类通常都有相同的父类。

类图:

简单工厂

优点:

  • 只关心创建过程,不关心具体业务,符合单一职责
  • 增加新的产品只需要,新增具体的产品并且修改工厂方法
  • 简单,只需要简单调用类的静态方法,传入参数即可
  • 降低了系统的耦合度,增加灵活性。实际开发中,传入的参数可以在配置文件中,进一步降低了系统耦合度

缺点:

  • 工厂类承担了所有产品的创建逻辑,职责过重
  • 增加了系统中类的个数,增加了系统的复杂度
  • 系统扩展困难,违背开闭原则

工厂方法模式

别名:虚拟构造器,多态工厂

定义:工厂父类负责定义创建产品对象的公共接口,类的实例化操作延迟到子类。

类图:

工厂方法模式

优点:

  • 向客户隐藏具体产品类实例化的具体细节
  • 让工厂自主确定实例化何种产品对象
  • 完全符合开闭原则,可以在不修改工厂角色的前提下引进新的产品

缺点:

  • 复杂度增加,类的个数随着产品类型的增加,成对增加
  • 增加系统的理解难度

抽象工厂模式

别名:Kit模式

概念:

  • 产品等级结构:产品的继承结构
  • 产品组:同一个工厂生产的不同产品等级结构的一组产品

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

类图:

抽象工厂模式

优点:

  • 隔离了具体类的生成
  • 保证客户可以始终使用同一个产品组的对象
  • 符合开闭原则。在产品组一侧符合开闭原则,只需要简单增加工厂即可

缺点:

  • 增加新的产品等级结构比较复杂,违背开闭原则

使用条件:

  • 不依赖于产品实例如何被创建,组合和表达的细节
  • 每次只使用某一产品组
  • 属于同一产品组的产品将在一起使用
  • 产品等级结构稳定

三种工厂模式对比

三个模式都属于工厂模式,含义就是使用工厂生产产品

将生产产品的一个或者一系列方法封装到一个类中,这样的类叫做工厂类;被实例化的类那就是产品类

  1. 简单工厂

    优点:简单,静态工厂方法,可以创建所有类型的产品

    缺点:职责重,单个类复杂度高;不符合开闭原则

    描述:支持同一等级结构中的任意产品,不支持扩展增加产品

  2. 工厂方法

    优点:降低工厂的负担;完全符合开闭原则

    缺点:类的个数成对增加;对于形成产品族的情况处理复杂

    描述:支持同一等级结构的固定产品(支持扩展增加产品)

  3. 抽象工厂

    优点:针对产品族场景的优化;产品组符合开闭原则

    缺点:模式复杂,只适用于产品族的场景

    描述:支持不同产品族的全部产品(不支持增加产品类型,支持增加产品族)

建造者模式

定义:将一个复杂对象的构建它的表示分离,使得同样的构建过程创建不同的表示。建造者模式就是一步一步构建一个复杂的对象,它允许用户只通过指定的类型和内容就可以构建他们,用户不需要知道内部的具体构建细节。

类图:

建造者模式

优点:

  • 将产品的创建过程和产品的表示解耦,使得创建过程可以创建不同的产品对象
  • 可以很方便的创建具体的建造者或者增加新的具体建造者,符合开闭原则
  • 便于更加精细的控制产品的创建过程

缺点:

  • 产品之间差异很大,不适合使用建造者模式
  • 如果产品内部变化复杂,可能会需要定义很多具体建造这类来适应这种变化

场景:

  • 需要生成的对象有很复杂的内部结构
  • 需要生成的对象属性存在相互依赖
  • 对象的创建过程独立于创建该对象的类
  • 隔离复杂对象的创建和表示

原型模式

定义:用原型实例指定创建对象的种类,并且通过复制这些原型创建新的对象

工作原理:

  • 通过请求原型对象复制自己来实现创建的过程
  • 工厂类就是原型自身,工厂方法是负责对象的克隆方法
  • 克隆创建的对象是全新的对象,有独立的内存空间
  • 原型模式可以得到一系列相似但是不完全相同的对象

类图:

原型模式

优点:

  • 简化对象的创建过程,提高新实例的创建效率
  • 扩展性比较好
  • 简化创建结构,简单的一个方法可以克隆出一的新的对象
  • 可以使用深拷贝的方式来保存对象的状态

缺点:

  • 需要为每一个类实现克隆方法,对已有的类进行改造时,需要修改源代码,违背了开闭原则
  • 深拷贝的方式需要编写较为复杂的代码

场景:

  • 创建新对象成本比较大,可以通过复制对象来获得
  • 需要保存对象的状态,而且对象的状态变化小
  • 避免使用分层次的工厂类来创建分层次的对象

扩展:

  • 原型管理器

单例模式

定义:确保一个类只有一个实例,而且自行实例化并且向整个系统提供这个实例。

类图:

单例模式

优点:

  • 对唯一实例受控访问
  • 节约资源,提高系统性能
  • 允许可变数量(有限个)的实例(多例模式)

缺点:

  • 扩展困难(缺少抽象层)
  • 单例类职责重。一个业务类不应该关心自己是不是单例,但是单例模式要把模式和业务混合在一起
  • 垃圾回收机制,可能导致共享单例对象的状态丢失

场景:

  • 系统只需要一个这个类的实例,或者资源只允许创建一个对象实例
  • 客户调用类的单个实例,只允许使用一个公共访问点