【设计模式】原型模式

2023-11-17

原型模式(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 读取二进制流。

实现

我们将创建一个抽象类 Shape 和扩展了 Shape 类的实体类。下一步是定义类 ShapeCache,该类把 shape 对象存储在一个 Hashtable 中,并在请求的时候返回它们的克隆。

PrototypePatternDemo 类使用 ShapeCache 类来获取 Shape 对象。

原型模式的 UML 图

步骤 1

创建一个实现了 Cloneable 接口的抽象类。

Shape.java

public abstract class Shape implements Cloneable {
   
   private String id;
   protected String type;
   
   abstract void draw();
   
   public String getType(){
      return type;
   }
   
   public String getId() {
      return id;
   }
   
   public void setId(String id) {
      this.id = id;
   }
   
   public Object clone() {
      Object clone = null;
      try {
         clone = super.clone();
      } catch (CloneNotSupportedException e) {
         e.printStackTrace();
      }
      return clone;
   }
}

步骤 2

创建扩展了上面抽象类的实体类。

Rectangle.java

public class Rectangle extends Shape {
 
   public Rectangle(){
     type = "Rectangle";
   }
 
   @Override
   public void draw() {
      System.out.println("Inside Rectangle::draw() method.");
   }
}

Square.java

public class Square extends Shape {
 
   public Square(){
     type = "Square";
   }
 
   @Override
   public void draw() {
      System.out.println("Inside Square::draw() method.");
   }
}

Circle.java

public class Circle extends Shape {
 
   public Circle(){
     type = "Circle";
   }
 
   @Override
   public void draw() {
      System.out.println("Inside Circle::draw() method.");
   }
}

步骤 3

创建一个类,从数据库获取实体类,并把它们存储在一个 Hashtable 中。

ShapeCache.java

import java.util.Hashtable;
 
public class ShapeCache {
    
   private static Hashtable<String, Shape> shapeMap 
      = new Hashtable<String, Shape>();
 
   public static Shape getShape(String shapeId) {
      Shape cachedShape = shapeMap.get(shapeId);
      return (Shape) cachedShape.clone();
   }
 
   // 对每种形状都运行数据库查询,并创建该形状
   // shapeMap.put(shapeKey, shape);
   // 例如,我们要添加三种形状
   public static void loadCache() {
      Circle circle = new Circle();
      circle.setId("1");
      shapeMap.put(circle.getId(),circle);
 
      Square square = new Square();
      square.setId("2");
      shapeMap.put(square.getId(),square);
 
      Rectangle rectangle = new Rectangle();
      rectangle.setId("3");
      shapeMap.put(rectangle.getId(),rectangle);
   }
}

步骤 4

PrototypePatternDemo 使用 ShapeCache 类来获取存储在 Hashtable 中的形状的克隆。

PrototypePatternDemo.java

public class PrototypePatternDemo {
   public static void main(String[] args) {
      ShapeCache.loadCache();
 
      Shape clonedShape = (Shape) ShapeCache.getShape("1");
      System.out.println("Shape : " + clonedShape.getType());        
 
      Shape clonedShape2 = (Shape) ShapeCache.getShape("2");
      System.out.println("Shape : " + clonedShape2.getType());        
 
      Shape clonedShape3 = (Shape) ShapeCache.getShape("3");
      System.out.println("Shape : " + clonedShape3.getType());        
   }
}

步骤 5

执行程序,输出结果:

Shape : Circle
Shape : Square
Shape : Rectangle

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【设计模式】原型模式 的相关文章

  • DenseNet学习与实现

    Densely Connected Convolutional Networks 提出了DenseNet 它用前馈的方式连接每一层与所有其他层 L层网络共有 L L 1

随机推荐

  • 解决:org.codehaus.jackson.JsonParseException:Unexpected end-of-input: expected close marker for OBJEC

    解决 org codehaus jackson JsonParseException Unexpected end of input expected close marker for OBJECT 文章目录 解决 org codehaus
  • ora-01578: oracle 数据块损坏,Oracle ORA-01578坏块解决方法

    本帖最后由 paulyi 于 2014 1 19 13 15 编辑 一 出问题时的情景 我在自己测试数据库上给大表 tb table导完数据后 建立索引时 出现以下错误 ORA 01578 ORACLE data block corrupt
  • 数字化时代-29:CSDN排名规则详细解读

    最近在CSDN的总榜单上一直徘徊在1000名出头 每周有二十多篇的新的原创文章 总积分也在持续增长 但排名一直没有进步 我很好奇 难道其他1000名左右的创造者的都这么疯狂 每周都会发表20篇以上的文章 于是怀着好奇心研读了一下CSDN排名
  • 利用vue-cli脚手架创建项目

    利用vue cli脚手架创建项目 安装vue cli脚手架 全局安装 npm install g vue cli 使用vue version查看是否安装完成 显示对应版本号 使用命令行创建 vue create 项目名称 default包含
  • 几个高危端口

    注意到检测系统显示的高危漏洞分别是22 135 139 445 3389端口 今天就分别了解下这些端口一般情况下是干什么用的 22 22端口一般用于ssh的数据传输 一般linux系统 除非你直接在终端上操作 不然你多半会通过ssh连接到l
  • 吐血推荐!5款好用又骚气的神站!真的有毒!(附网址)

    1 交互式元素周期表 https ptable com 喜欢化学的同学千万不要错过了 这里可以在线学习交互式元素周期表 想知道什么元素 让你学习到丰富的化学元素知识 2 无聊巨作VII第二部 http www spielzeugz de h
  • 使用StarUML创建类图

    1 综述 What StarUML是一种生成类图和其他类型的UML图表的工具 本文是一个使用StarUML创建类图 Java语言描述 的简明手册 StarUML 简称SU 是一种创建UML类图 并能够自动生成Java的 stub code
  • 概说概要设计怎么做

    概说概要设计怎么做 51CMM COM原创 作者 厦门巨龙软件工程有限公司 卢琳生 2003 12 22 摘要 本文是在概要设计实践和学习中的一些心得与学习笔记 希望与大家分享 如有不妥之处欢迎指正 关键字 概要设计 结构化 OOD 正文
  • 大数据学习-3.Linux下Web服务器的搭建与配置

    文章目录 简介 一 关闭防火墙和selinux 1 关闭防火墙 1 关闭selinux 二 Web服务器与配置 1 Apache 2 Nginx 简介 本文主要介绍在CentOS下 Apache与Nginx 服务的搭建与配置 一 关闭防火墙
  • springboot redis Unsatisfied dependency expressed through method ‘redisTemplate‘ parameter 0

    pom xml中导入包更换写
  • SpringBoot RabbitMq 六大模式

    目录 依赖 配置 简单队列 模型 代码示例 工作队列 模型 代码示例 订阅模式 模型 代码示例 路由模式 模型 代码示例 主题模式 模型 代码示例 RPC 依赖 配置 依赖
  • 【华为机试在线训练】Day 10

    自动售货系统 题目描述 1 总体说明 考生需要模拟实现一个简单的自动售货系统 实现投币 购买商品 退币 查询库存商品及存钱盒信息的功能 系统初始化时自动售货机中商品为6种商品 商品的单价参见1 1规格说明 存钱盒内放置1元 2元 5元 10
  • POJ - 3259 Wormholes

    While exploring his many farms Farmer John has discovered a number of amazing wormholes A wormhole is very peculiar beca
  • linux网络全景指南

    自我介绍 腾讯云网络高级工程师 腾讯云网络核心开发人员 欢迎微信搜索 职场重生 关注公众号 职场重生 后续更多精彩内容发布 万字长文 建议收藏 引言 本期分享一个比较常见的 络问题 丢包 例如我们去ping 个 站 如果能ping通 且 站
  • python画散点图-python学习之matplotlib绘制散点图实例

    要绘制单个点 可使用函数scatter 并向其传递一对x和y坐标 它将在指定位置绘制一个点 使用scatter 绘制散点图 import matplotlib pyplot as plt plt scatter 2 4 plt show 下
  • visual studio 的各个版本下载地址,很全,从 6.0 一直 到 vs2013,要的拿去吧

    Microsoft Visual Studio 6 0 下载 英文版360云盘下载 http l11 yunpan cn lk sVeBLC3bhumrI 英文版115网盘下载 http 115 com file bew2qrau 英文版迅
  • org.springframework.transaction.UnexpectedRollbackException 解决

    1 异常 org springframework transaction UnexpectedRollbackException Transaction rolled back because it has been marked as r
  • TXT文本文件存储

    个人简介 作者简介 大家好 我是W chuanqi 一个编程爱好者 个人主页 W chaunqi 支持我 点赞 收藏 留言 愿你我共勉 若身在泥潭 心也在泥潭 则满眼望去均是泥潭 若身在泥潭 而心系鲲鹏 则能见九万里天地 文章目录 TXT
  • 【C++】细说C++中的数组之“静态”数组

    转自博主 https blog csdn net u013921430 article details 79514972 感谢分享 以备学习
  • 【设计模式】原型模式

    原型模式 Prototype Pattern 是用于创建重复的对象 同时又能保证性能 这种类型的设计模式属于创建型模式 它提供了一种创建对象的最佳方式之一 这种模式是实现了一个原型接口 该接口用于创建当前对象的克隆 当直接创建对象的代价比较