文章目录
- 原型模型
- 模式的实现
- 简单工厂模式
- 工厂方法模式
- 优点:
- 缺点:
- 应用场景
- 模式的结构和实现
- 抽象工厂模式
- 定义
- 缺点:
- 模式的结构与实现
- 抽象工厂模式的应用场景
- 扩展
原型模型
在系统中,存在大量相同或者相似的创建问题,如果用传统的构造函数来创建对象,会比较复杂且耗时耗资源,用原型模式生产对象就很高效,就像孙悟空拔下猴毛轻轻一吹就变出很多孙悟空一样简单。
定义:
- ==用一个已经创建的实例作为模型,通过复制该原型对象来创建一个和原型相同或相似的新对象,==这里原型实例指定了要创建的对象的种类.
- 用这种方式创建对象非常高效,根本无须知道对象创建的细节。
优点:
- Java自带的原型模式基于内存二进制流的复制,在性能上直接NEW一个对象等价优良
- 可以使用深克隆方式保存对象的状态,使用原型模式将对象复制一份,并将其状态保存起来,简化了创建对象的过程,以便在需要的时候使用(例如恢复到历史某一状态),可辅助实现撤销操作。
缺点:
- 需要为每一个类都配置一个clone方法
- clone方法位于类的内部,当对已有类进行改造的时候,需要修改代码,违背了开闭原则。
- 当使用深克隆时,需要编写较为复杂的代码,且当对象之间存在多重嵌套引用,为了实现深克隆,每一层对象对应的类都必须支持深克隆,实现起来会比较麻烦,因此,深克隆、浅克隆需要运用得当。
原型模式的结构与实现
Java 提供了对象的 clone() 方法,所以用 Java 实现原型模式很简单
主要角色:
- 抽象原型类:规定了具体原型对象必须实现的接口。
- 具体原型类:实现抽象原型类的 clone() 方法,它是可被复制的对象。
- 访问类:使用具体原型类中的 clone() 方法来复制新的对象。
模式的实现
原型模式分为=浅克隆和深克隆
- 浅克隆: 创建一个新对象,新对象的属性和原来对象完全相同,对于非基本类型属性,仍指向原有属性所指向的对象的内存地址
- 深克隆:创建一个新对象,属性种引用的其他对象也会被克隆,不在指向原有的对象地址
java中的Object类提供了浅克隆的方法clone() 方法,具体原型类只要实现 Cloneable 接口就可实现对象的浅克隆,这里的 Cloneable 接口就是抽象原型类。
原型模式的引用场景
- 对象之间相同或相似,即只是个别的几个属性不同的时候
- 创建对象成本大,例如初始化时间长,占用CPU太多.,或者占用网络资源太多,需要优化资源
- 创建一个对象需要繁琐的数据准备或访问权限等,需要提高性能或者提高安全性
- 系统中大量使用该类的对象,而且各个调用者都需要给它的属性重新赋值
在spring中,原型模型应用广泛,例如Scope=‘prototype’,JSON.parseObject() 等都是原型模式的具体应用。
创建型模式-工厂模式
工厂模式相关代码
在日常开发中,凡是需要生成复杂对象的地方,都可以尝试考虑使用工厂模式来代替。
工厂模式定义:定义一个创建产品对象的工厂接口,将产品对象的实际创建工作推迟到具体子工厂类中,这满足创建模型中所要的创建与使用相分离
的特点
按照实例业务划分为
- 简单工厂模式
- 工厂方法模式
- 抽象工厂模式
简单工厂模式
创建的对象称为产品
,把创建产品的对象称为工厂
,如果要创建的产品不多,只要一个工厂类就可以完成,这种模式叫简单工厂模式
。
在简单工厂模式中创建实例的方法通常为静态(static)方法,因此简单工厂模式(Simple Factory Pattern)又叫作静态工厂方法模式(Static Factory Method Pattern)。
简单工厂模式有一个具体的工厂类,可以生产多个不同的产品,属于创建型设计模式。简单工厂模式不在 GoF 23 种设计模式之列。
简单工厂模式每增加一个产品就要增加一个具体产品类和一个对应的具体工厂类,这增加了系统的复杂度,违背了“开闭原则”。
“工厂方法模式”是对简单工厂模式的进一步抽象化,其好处是可以使系统在不修改原来代码的情况下引进新的产品,即满足开闭原则。
优点:
- 工厂类包含必要的逻辑判断,可以决定在什么时候创建哪一个产品的实例.
- 客户端无需知道所创建具体产品的类名,只需知道参数即可
- 也可以引用配置文件,在不修改客户端代码的情况下更换和添加新的具体产品类。
缺点:
- 简单工厂模式的工厂类单一,负责所有产品的创建,职责过重,一旦异常,整个系统将受影响,代码用子,违背了高聚合原则
- 使用简单工厂模式会增加系统中类的个数(引入新的工厂类),增加系统的复杂度和理解难度
- 系统扩展困难,一旦增加新产品不得不修改工厂逻辑,在产品类型较多时,可能造成逻辑过于复杂
- 简单工厂模式使用了 static 工厂方法,造成工厂角色无法形成基于继承的等级结构。
工厂方法模式
工厂方法模式是对简单工厂模式的进一步抽象化,其好处是可以不修改原来代码的情况下引进新的产品,即满足开闭原则
优点:
- 用户只需知道具体工厂的名称就可得到所要的产品,无需知道产品的具体创建过程。
- 灵活性强,对于新产品的创建,只需多写一个相应的工厂类
- 经典的解耦框架,高层模块只需要知道产品的抽象类,无需关心替他实现类,满足满足迪米特法则、依赖倒置原则和里氏替换原则。
缺点:
- 类的个数容易过多,增加复杂度
- 增加了系统的抽象性和理解难度
- 抽象产品只能生产一种产品,此弊端可使用抽象工厂模式解决。
应用场景
- 客户只知道创建产品的工厂名,而不知道具体的产品名。如 TCL 电视工厂、海信电视工厂等。
- 创建对象的任务由多个具体子工厂中的某一个完成,而抽象工厂只提供创建产品的接口。
- 客户不关心创建产品的细节,只关心产品的品牌
模式的结构和实现
工厂方法模式由抽象工厂,具体工厂,抽象产品和具体产品等四个要素构成,
模式的结构
- 抽象工厂
提供了创建产品的接口,调用者通过它访问具体工厂的工厂方法 newProduct() 来创建产品。
- 具体工厂
主要是实现抽象工厂中的抽象方法,完成具体产品的创建。
- 抽象产品
定义了产品的规范,描述了产品的主要特性和功能
- 具体产品
实现了抽象产品角色所定义的接口,由具体工厂来创建,它同具体工厂之间一一对应。
工厂模式中只中考虑的是一类产品的生产,如畜牧场只养动物、电视机厂只生产电视机、计算机软件学院只培养计算机软件专业的学生等。
工厂方法模式只考虑生产同等级的产品
抽象工厂模式
定义
是一种为访问类提供一个创建一组相关或相互依赖对象的接口,且访问类无须指定所要产品的具体类就能得到同族的不同等级的产品的模式结构。
抽象工厂模式是工厂方法模式的升级版本,工厂方法模式只生产一个等级的产品,而抽象工厂模式可生产多个等级的产品。
使用抽象工厂模式一般要满足以下条件
- 系统中有多个产品族,每个具体工厂创建同一族但属于不同等级结构的产品
- 系统一次只可能消费其中某一族产品,即同族的产品一起使用
抽象工厂模式除了具有工厂方法模式的优点外,其他主要优点如下
- 可以在类的内部对产品族中相关的多等级产品共同管理,而不必专门引入多个新的类来进行管理。
- 当需要产品族时,抽象工厂可以保证客户端始终只使用同一个产品的产品组。
- 抽象工厂增强了程序的可扩展性,当增加一个新的产品族时,不需要修改原代码,满足开闭原则。
缺点:
当产品族中需要增加一个新的产品时,所有的工厂类都需要进行修改,增加了系统的抽象性和理解难度
模式的结构与实现
抽象工厂模式同工厂方法模式一样,也是由抽象工厂、具体工厂、抽象产品和具体产品等 4 个要素构成,但抽象工厂中方法个数不同,抽象产品的个数也不同
- 抽象工厂:提供了创建产品的接口,包含多个创建产品的方法 newProduct(),可以创建多个不同等级的产品。
- 具体工厂: 主要是实现具体抽象工厂中的多个抽象方法,完成具体产品的创建
- 抽象产品:定义了产品的规范,描述了产品的主要特性和功能,抽象工厂模式有多个抽象产品
- 具体产品: 实现了抽象产品角色所定义的接口,由具体工厂来创建,它同具体工厂之间是多对一的关系。
抽象工厂模式的应用场景
抽象工厂模式最早的应用是用于创建属于不同操作系统的视窗构件
适用于以下场景
- 当需要创建的对象是一系列相互关联或相互依赖的产品族时,如电器工厂中的电视机、洗衣机、空调等。
- 系统中有多个产品族,但是每次只是使用其中的某一族产品,如果人只喜欢穿某一个品牌的衣服和鞋.
- 系统中提供了产品的类库,且所有产品的接口相同,客户端不依赖产品实例的创建细节和内部结构。
扩展
抽象工厂模式的扩展有一定的“开闭原则”倾斜性:
- 当增加一个新的产品族时只需增加一个新的具体工厂,不需要修改原代码,满足开闭原则。
- 当产品族中需要增加一个新种类的产品时,则所有的工厂类都需要进行修改,不满足开闭原则。