文章目录

  • 1 原型模式介绍
  • 2 原型模式详解
    • 2.1 原型模式结构
    • 2.2 深克隆与浅克隆
      • 2.2.1 浅克隆
      • 2.2.2 深克隆
    • 2.3 原型模式实现
      • 2.3.1 通用实现方法
      • 2.3.2 Java语言中的clone()方法和Cloneable接口
    • 2.4 原型模式应用举例
  • 3 原型管理器
    • 3.1 原型管理器实现
    • 3.2 原型管理器应用举例

1 原型模式介绍

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

它的工作原理很简单:将一个原型对象传给要发动创建的对象(即客户端对象),这个要发动创建的对象通过请求原型对象复制自己来实现创建过程。

意图: 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。

主要解决: 在运行期建立和删除原型。

何时使用: 1、当一个系统应该独立于它的产品创建,构成和表示时。 2、当要实例化的类是在运行时刻指定时,例如,通过动态装载。 3、为了避免创建一个与产品类层次平行的工厂类层次时。 4、当一个类的实例只能有几个不同状态组合中的一种时。建立相应数目的原型并克隆它们可能比每次用合适的状态手工实例化该类更方便一些。

如何解决: 利用已有的一个原型对象,快速地生成和原型对象一样的实例。

关键代码: 1、实现克隆操作,在 JAVA 继承 Cloneable,重写 clone(),在 .NET 中可以使用 Object 类的 MemberwiseClone() 方法来实现对象的浅拷贝或通过序列化的方式来实现深拷贝。 2、原型模式同样用于隔离类对象的使用者和具体类型(易变类)之间的耦合关系,它同样要求这些"易变类"拥有稳定的接口。

应用实例: 1、细胞分裂。 2、JAVA 中的 Object clone() 方法。

优点: 1、性能提高。 2、逃避构造函数的约束。

缺点: 1、配备克隆方法需要对类的功能进行通盘考虑,这对于全新的类不是很难,但对于已有的类不一定很容易,特别当一个类引用不支持串行化的间接对象,或者引用含有循环结构的时候。 2、必须实现 Cloneable 接口。

使用场景: 1、资源优化场景。 2、类初始化需要消化非常多的资源,这个资源包括数据、硬件资源等。 3、性能和安全要求的场景。 4、通过 new 产生一个对象需要非常繁琐的数据准备或访问权限,则可以使用原型模式。 5、一个对象多个修改者的场景。 6、一个对象需要提供给其他对象访问,而且各个调用者可能都需要修改其值时,可以考虑使用原型模式拷贝多个对象供调用者使用。 7、在实际项目中,原型模式很少单独出现,一般是和工厂方法模式一起出现,通过 clone 的方法创建一个对象,然后由工厂方法提供给调用者。原型模式已经与 Java 融为浑然一体,大家可以随手拿来使用。

注意事项: 与通过对一个类进行实例化来构造新对象不同的是,原型模式是通过拷贝一个现有对象生成新对象的。浅拷贝实现 Cloneable,重写,深拷贝是通过实现 Serializable 读取二进制流。

2 原型模式详解

2.1 原型模式结构


原型模式包含以下3个角色。

  1. Prototype(抽象原型类):它是声明克隆方法的接口,是所有具体原型类的公共父类,它可以是抽象类也可以是接口,甚至还可以是具体实现类。
  2. ConcretePrototype(具体原型类):它实现在抽象原型类中声明的克隆方法,在克隆方法中返回自己的一个克隆对象。
  3. Client(客户类):在客户类中,让一个原型对象克隆自身从而创建一个新的对象,只需要直接实例化或通过工厂方法等方式创建一个原型对象,再通过调用该对象的克隆方法即可得到多个相同的对象。

2.2 深克隆与浅克隆

根据在复制原型对象的同时是否复制包含在原型对象中引用类型的成员变量,原型模式的克隆机制可分为两种,即浅克隆(Shallow Clone)和深克隆(Deep Clone)。

2.2.1 浅克隆

在浅克隆中,如果原型对象的成员变量是值类型,将复制一份给克隆对象;如果原型对象的成员变量是引用类型,则将引用对象的地址复制一份给克隆对象,也就是说原型对象和克隆对象的成员变量指向相同的内存地址。简单来说,在浅克隆中,当对象被复制时只复制它本身和其中包含的值类型的成员变量,而引用类型的成员对象并没有复制。

2.2.2 深克隆

在深克隆中,无论原型对象的成员变量是值类型还是引用类型,都将复制一份给克隆对象,深克隆将原型对象的所有引用对象也复制一份给克隆对象。简单来说,在深克隆中,除了对象本身被复制外,对象所包含的所有成员变量也将复制。

2.3 原型模式实现

实现原型模式的关键在于如何实现克隆方法。这里介绍两种在Java语言中最常用的克隆实现方法。

2.3.1 通用实现方法

通用的克隆实现方法是在具体原型类的克隆方法中实例化一个与自身类型相同的对象并将其返回,同时将相关的参数传入新创建的对象中,保证它们的成员变量相同。

典型的抽象原型类代码如下:

public abstract class Prototype {public abstract Prototype clone();
}

典型的具体原型类代码如下:

public class ConcretePrototype extends Prototype {private String name; // 成员变量public void setName(String name) {this.name = name;}public void getName() {return this.name;}// 克隆方法实现public Prototype clone() {Prototype prototype = new ConcretePrototype(); // 创建新对象prototype.setName(this.name);return prototype;}
}

这样我们就只需要在客户类中创建一个ConcretePrototype对象作为原型对象,然后调用其clone()方法即可得到对应的克隆对象。

此方法是原型模式的通用实现,它与编程语言本身的特性无关,其他面向对象编程语言也可以使用这种形式来实现对原型对象的克隆。

在这种通用实现方法中,可通过手工编写clone()方法来实现浅克隆和深克隆。对于引用类型的对象,可以在clone()方法中通过赋值的方式来实现复制,这是一种浅克隆实现方案;如果在clone()方法中通过创建一个全新的成员对象来实现复制,则是一种深克隆实现方案。

2.3.2 Java语言中的clone()方法和Cloneable接口

在Java语言中,所有的Java类均继承自java.lang.Object类,Object类提供了一个clone()方法,可以将一个Java对象复制一份。因此在Java中可以直接使用Object提供clone()方法来实现对象的浅克隆。

需要注意的是能够实现克隆的Java类都必须实现一个标识接口Cloneable,表示这个Java类支持被复制。如果一个类没有实现这个接口但是调用了clone()方法,Java编译器将会抛出一个CloneNotSupportedException异常。如下代码所示:

public class ConcretePrototype implements Cloneable {public Prototype clone() {Object object = null;try {object = super.clone(); // 浅克隆} catch (CloneNotSupportedException exception) {System.err.println("Not support Cloneable");}return (Prototype)object;}
}

为了获取对象的一个克隆,可以直接利用Object类的clone()方法,其具体步骤如下:

  1. 在派生类中覆盖基类的clone()方法,并声明为public。
  2. 在派生类的clone()方法中调用super.clone()。
  3. 派生类需实现Cloneable接口。

此时,Object类相当于抽象原型类,所有实现了Cloneable接口的类相当于具体原型类。

2.4 原型模式应用举例

  • 题目描述

    某数据处理软件需要增加一个图表复制功能。在图表对象(DataChart)中包含一个数据集对象(DataSet)。数据集对象用于封装要显示的数据,用户可以通过界面上的复制按钮将该图表复制一份,复制后,即可得到新的图表对象,然后可以修改新图表的编号、颜色、数据。试用原型模式设计软件实现深克隆。

  • UML类图

    在该设计方案中,DataChart 类包含一个 DataSet 对象,在复制 DataChart 对象的同时将
    复制 DataSet 对象,因此需要使用深克隆技术,可使用流来实现深克隆。其中Serializable是java.io包中定义的、用于实现Java类的序列化操作而提供的一个语义级别的接口。Serializable序列化接口没有任何方法或者字段,只是用于标识可序列化的语义。实现了Serializable接口的类可以被ObjectOutputStream转换为字节流,同时也可以通过ObjectInputStream再将其解析为对象。故我们实现这个接口即可使用流来实现深克隆

  • 代码

    代码地址

3 原型管理器

3.1 原型管理器实现

原型管理器(Prototype Manager)是将多个原型对象存储在一个集合中供客户端使用,它是一个专门负责克隆对象的工厂,其中定义了一个集合用于存储原型对象, 如果需要某个原型对象的一个克隆,可以通过复制集合中对应的原型对象来获得。 在原型管理器中针对抽象原型类进行编程,以便扩展。 其结构如图所示:

其中典型的原型管理器PrototypeManager类的实现代码片段如下:

package prototype_pattern;import java.util.Hashtable;/*** @author Cnc_hzf* @date 2022/4/22 15:00*/
public class PrototypeManager {private Hashtable prototypeTable = new Hashtable(); // 使用Hashtable存储原型对象public PrototypeManager() {prototypeTable.put("A", new ConcretePrototypeA());prototypeTable.put("B", new ConcretePrototypeB());}public void add(String key, Prototype prototype) {prototypeTable.put(key, prototype);}public Prototype get(String key) {Prototype clone = ((Prototype) prototypeTable.get(key)).clone(); // 通过克隆方法创建新对象return clone;}
}

在实际开发中可以将PrototypeManger设计为单例类,确保系统中有且仅有一个PrototypeManager对象,这样既有利于节省系统资源,还可以更好地对原型管理器对象进行控制。

3.2 原型管理器应用举例

  • 题目描述

    某公司需要创建一个公文管理器,公文管理器中需要提供一个集合对象来存储一些公文模板,用户可以通过复制这些模板快速的创建新的公文,试使用带有原型管理器的原型模式来设计该公文管理器并使用Java代码编程模拟。

  • UML类图

    其中,OfficialDocument (抽象公文类)充当抽象原型类,其子类 FAR(Feasibility Analysis
    Report,可行性分析报告)和 SRS(Software Requirements Specification,软件需求规格说明书)充当具体原型类,PrototypeManager 充当原型管理器。

  • 代码

    代码地址

设计模式之原型模式详解(附应用举例实现)相关推荐

  1. java 肌汉模式_设计模式之原型模式详解(附源代码)

    原型模式(Prototype Pattern) 原型模式(Prototype Pattern)是用于创建重复的对象,同时又能保证性能.这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式. ...

  2. 设计模式(四)——原型模式详解

    设计模式(四)--原型模式详解 定义 结构 实现 案例 浅克隆 深克隆 定义 原型模式就是用一个已经创建的实例作为原型,通过复制该原型对象来创建一个和原型对象相同的对象. 结构 原型模式包含以下角色: ...

  3. 设计模式-值类型与引用类型、深拷贝与浅拷贝、原型模式详解

    一. 值类型和引用类型 1. 前言 (1). 分类 值类型包括:布尔类型.浮点类型(float.double.decimal.byte).字符类型(char).整型(int.long.short等). ...

  4. IoC与DI工厂、单例、原型模式详解

    1.工厂模式 1.1 工厂模式的由来 在现实生活中我们都知道 原始社会自给自足(没有工厂) 农耕社会有了小作坊(简单工厂,如民间酒坊) 工业革命后有了流水线(工厂方法,自产自销) 现代产业链中有代工厂 ...

  5. 设计模式之模板方法模式详解

    设计模式之模板方法模式详解 概述 在面向对象程序设计过程中,程序员常常会遇到这种情况:设计一个系统时知道了算法所需的关键步骤,而且确定了这些步骤的执行顺序,但某些步骤的具体实现还未知,或者说某些步骤的 ...

  6. 设计模式之门面模式详解

    设计模式之门面模式详解 文章目录 设计模式之门面模式详解 一.什么是门面模式 二.门面模式的应用场景 三.门面模式的角色组成 四.门面模式通用写法 五.门面模式在业务中的应用 六.门面模式优缺点 一. ...

  7. 设计模式——模版方法模式详解(论沉迷LOL对学生的危害)

    0. 前言 写在最前面,本人的设计模式类博文,建议先看博文前半部分的理论介绍,再看后半部分的实例分析,最后再返回来复习一遍理论介绍,这时候你就会发现我在重点处标红的用心,对于帮助你理解设计模式有奇效哦 ...

  8. 设计模式之桥接模式详解

    设计模式之桥接模式详解 文章目录 设计模式之桥接模式详解 一.什么是桥接模式 二.桥接模式的应用场景 三.桥接模式的角色组成 四.桥接模式通用写法示例 五.桥接模式优缺点 一.什么是桥接模式 桥接模式 ...

  9. 设计模式之策略模式详解

    设计模式之策略模式详解 概述 先看下面的图片,我们去旅游选择出行模式有很多种,可以骑自行车.可以坐汽车.可以坐火车.可以坐飞机. 作为一个程序猿,开发需要选择一款开发工具,当然可以进行代码开发的工具有 ...

最新文章

  1. Web 开发时需要注意到的一些性能问题
  2. SAP Fiori里的manifest.json
  3. oslo.config资源
  4. Guns导入开发工具
  5. linux应用程序逆向,Linux下查看并下载命令源码包(根据命令/应用程序逆向获取并且安装其所属源码包)...
  6. 加个ing是什么意思_英语中动词ed和ing形式作形容词时用法有啥区别,牢记以下要点!...
  7. jpa存储byte到postgresql
  8. Java多线程之后台线程不执行finally
  9. 心情的旅行- 让自己慢下来(46)
  10. Star Schema完全参考手册读书笔记三
  11. C++回声服务器_6-多进程pipe版本服务器
  12. oracle语句执行过程
  13. 在内网中使用maven_使用nexus搭建内网maven镜像
  14. 机器学习之随机森林算法
  15. 勒索病毒是什么?如何防勒索病毒
  16. 粒子系统(particle system)
  17. idea Translation翻译插件失效解决办法
  18. 软件测试,作为职场新鸟?我该怎么办?看看资深5年测试的见解......
  19. Android数据库处理重复插入Insert数据的问题
  20. 命令行 按表模糊查询导出orecal数据库

热门文章

  1. IDEA maven项目变灰
  2. 多人合作时代码提交 git 操作
  3. 微信小程序中的快捷键
  4. Aspose.Words导出html到word
  5. leetcode:1154. 一年中的第几天
  6. fireFox浏览器蓝色版(开发版)下载地址
  7. 数据库SQL语言学习--上机练习2(连接查询 嵌套查询)
  8. (MacOS)来做一个简单带有音乐提醒的python倒计时器吧~
  9. 1. 客户机-服务器 模型
  10. 华为服务器查看系统版本,服务器操作系统版本查看命令