java设计模式4——原型模式

1、写在前面

本节内容与C++语言的复制构造函数、浅拷贝、深拷贝极为相似,因此建议学习者可以先了解C++的该部分的相关知识,或者学习完本节内容后,也去了解C++的相应内容,进行比对学习。

2、原型模式介绍

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

这种模式是实现了一个原型接口,该接口用于创建当前对象的克隆。当直接创建对象的代价比较大时,则采用这种模式。例如,一个对象需要在一个高代价的数据库操作之后被创建。我们可以缓存该对象,在下一个请求时返回它的克隆,在需要的时候更新数据库,以此来减少数据库调用。

3、java实现克隆的核心

1、实现一个接口(Cloneable)

2、重写一个方法(clone())

clone()方法的源码分析

protected native Object clone() throws CloneNotSupportedException;

由方法声明的放回值类型=>native,可知该方法实际上是一个C++封装好的方法,由java来进行调用,相当于C++语言的复制构造函数,但是又有所区别。

4、第一种原型模式实现(浅拷贝)

4.1、建立视频的原型类

package com.xgp.company.创建型模式.第四种_原型模式.demo1;

import java.util.Date;

/**
* 1、实现一个接口
* 2、重写一个方法
*/
//视频原型类
public class Video implements Cloneable {
private String name;
private Date createTime; /**
* 重写克隆方法
* @return
* @throws CloneNotSupportedException
*/
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
} public Video() { } public Video(String name, Date createTime) {
this.name = name;
this.createTime = createTime;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public Date getCreateTime() {
return createTime;
} public void setCreateTime(Date createTime) {
this.createTime = createTime;
} @Override
public String toString() {
return "Video{" +
"name='" + name + '\'' +
", createTime=" + createTime +
'}';
}
}

4.2、建立复制的客户端类

package com.xgp.company.创建型模式.第四种_原型模式.demo1;

import java.util.Date;

/**
* 客户端:克隆
*/
public class Client { public static void main(String[] args) throws CloneNotSupportedException {
//原型对象
Video v1 = new Video("狂神说java", new Date());
System.out.println("v1 = " + v1);
System.out.println("v1 = " + v1.hashCode()); System.out.println("========================");
//v1 克隆 v2
Video v2 = (Video) v1.clone();
System.out.println("v2 = " + v2);
System.out.println("v2 = " + v2.hashCode()); }
}

运行结果:

v1 = Video{name='狂神说java', createTime=Fri Feb 14 10:26:57 CST 2020}
v1 = 1836019240
========================
v2 = Video{name='狂神说java', createTime=Fri Feb 14 10:26:57 CST 2020}
v2 = 325040804

5、弊端

5.1、揭露弊端的代码

/**
* 演示浅克隆弊端
* @param args
* @throws CloneNotSupportedException
*/
public static void main(String[] args) throws CloneNotSupportedException {
//原型对象
Date date = new Date();
Video v1 = new Video("狂神说java", date);
System.out.println("v1 = " + v1);
System.out.println("v1 = " + v1.hashCode()); //v1 克隆 v2
Video v2 = (Video) v1.clone();
System.out.println("v2 = " + v2);
System.out.println("v2 = " + v2.hashCode()); System.out.println("========================"); date.setTime(22222222);
System.out.println("v1 = " + v1);
System.out.println("v1 = " + v1.hashCode()); //v1 克隆 v2
System.out.println("v2 = " + v2);
System.out.println("v2 = " + v2.hashCode()); }

5.2、弊端代码的运行结果

v1 = Video{name='狂神说java', createTime=Fri Feb 14 10:29:02 CST 2020}
v1 = 1836019240
v2 = Video{name='狂神说java', createTime=Fri Feb 14 10:29:02 CST 2020}
v2 = 325040804
========================
v1 = Video{name='狂神说java', createTime=Thu Jan 01 14:10:22 CST 1970}
v1 = 1836019240
v2 = Video{name='狂神说java', createTime=Thu Jan 01 14:10:22 CST 1970}
v2 = 325040804

5.3、弊端分析

从运行结果可以看出,当改变一个被v1,v2都引用的时间对象时,两者都发生了改变,没有将引用的对象进行复制,因此称之为浅拷贝。

5.4、模型图如下:

通过上面的模型图可以看到,被引用的对象还是只有一份,因此存在很大的弊端。在C++中,如果存在这种引用关闭,当程序员两次删除对象时,会出现第二次删对象时发生异常的情况。虽然在java语言中,有着gc机制,不需要程序员手动的去释放对象,不会出现重复删除的错误。但是,当被引用的对象发生改变时,很有可能会发生数据上的不正确。

6、改进(深拷贝模式)

6.1、我们期望想要改进后的模型图如下:被引用的对象也复制了一份,互不干扰。

6.2、实现方式:改造重写的克隆方法

@Override
protected Object clone() throws CloneNotSupportedException {
/**
* 改造克隆方法,进行生克隆
*/
Object obj = super.clone();
Video v = (Video) obj; //将对象的属性进行克隆
v.createTime = (Date) this.createTime.clone();
return obj;
}

6.3、此时的运行结果为:

v1 = Video{name='狂神说java', createTime=Fri Feb 14 10:37:33 CST 2020}
v1 = 1836019240
v2 = Video{name='狂神说java', createTime=Fri Feb 14 10:37:33 CST 2020}
v2 = 325040804
========================
v1 = Video{name='狂神说java', createTime=Thu Jan 01 14:10:22 CST 1970}
v1 = 1836019240
v2 = Video{name='狂神说java', createTime=Fri Feb 14 10:37:33 CST 2020}
v2 = 325040804

6.4、当原型引用的对像改变时,复制的对象并不发生改变,被引用的对象被复制了两份,因此称之为深拷贝。

java设计模式4——原型模式的更多相关文章

  1. JAVA 设计模式之原型模式

    目录 JAVA 设计模式之原型模式 简介 Java实现 1.浅拷贝 2.深拷贝 优缺点说明 1.优点 2.缺点 JAVA 设计模式之原型模式 简介 原型模式是六种创建型设计模式之一,主要应用于创建相同 ...

  2. java设计模式之原型模式

    原型模式概念 该模式的思想就是将一个对象作为原型,对其进行复制.克隆,产生一个和原对象类似的新对象.java中复制通过clone()实现的.clone中涉及深.浅复制.深.浅复制的概念如下: ⑴浅复制 ...

  3. java设计模式之五原型模式(Prototype)

    原型模式虽然是创建型的模式,但是与工程模式没有关系,从名字即可看出,该模式的思想就是将一个对象作为原型,对其进行复制.克隆,产生一个和原对象类似的新对象.本小结会通过对象的复制,进行讲解.在Java中 ...

  4. JAVA设计模式之 原型模式【Prototype Pattern】

    一.概述: 使用原型实例指定创建对象的种类,而且通过拷贝这些原型创建新的对象. 简单的说就是对象的拷贝生成新的对象(对象的克隆),原型模式是一种对象创建型模式. 二.使用场景: 创建新的对象能够通过对 ...

  5. JAVA 设计模式之 原型模式详解

    原型模式(Prototype Pattern)是指原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象. 原型模式利用的是克隆的原理,创建新的对象,JDK提供的Cloneable 和JSON. ...

  6. JAVA设计模式之原型模式(prototype)

    原型模式: 原型模式又叫克隆模式 Java自带克隆模式 实现克隆模式必须实现Cloneable 接口,如果不实现会发生java.lang.CloneNotSupportedException异常 当某 ...

  7. 孙悟空的身外身法术使用了Java设计模式:原型模式

    目录 定义 意图 主要解决问题 何时使用 优缺点 结构 简单形式的原型模式 登记形式的原型模式 两种形式比较 浅克隆和深克隆 孙悟空的身外身法术 浅克隆实现 深克隆实现 定义 原型模式属于对象的创建型 ...

  8. 设计模式_11_原型模式(prototype)深拷贝、浅拷贝

    设计模式_11_原型模式(prototype) 浅拷贝: package designPatternOf23; /** * 定义:用原型实例,指定创建对象的种类,并通过拷贝这些原型创建新的对象 * P ...

  9. 【GOF23设计模式】原型模式

    来源:http://www.bjsxt.com/ 一.[GOF23设计模式]_原型模式.prototype.浅复制.深复制.Cloneable接口  浅复制 package com.test.prot ...

随机推荐

  1. quick-cocos2d-x项目《狂点小怪兽》总结

    最近找了个公司实习,领导让我把公司的<狂点小怪兽>C++游戏用Lua重写.大概用了一个星期完成. 第一次使用quick-cocos2d-x,磕磕碰碰的也算是走了一遍流程. 1. quick ...

  2. C语言的安装及使用

    安装 vc6.0 使用方法 new    ---  win32 Console Application ---  ok-ok     ------c++ Source File      ------ ...

  3. 架构模式中的Active Record和Data Mapper

    架构模式中的Active Record和Data Mapper 概念 在简单应用中,领域模型是一种和数据库结构一致的简单结构,对应每个数据库表都有一个领域类,在这种情况下,有必要让每个对象负责数据库的 ...

  4. OpenCV3入门(二)Mat操作

    1.Mat结构 1.1.Mat数据 Mat本质上是由两个数据部分组成的类: 矩阵头:包含信息有矩阵的大小,用于存储的方法,矩阵存储的地址等 数据矩阵指针:指向包含了像素值的矩阵. 矩阵头部的大小是恒定 ...

  5. ORACLE ITL事务槽

    讲到ITL(事务槽)必定先说数据块,那么什么是数据块呢?先给大家上一个数据块结构图 数据块分别由块头.ITL(事务槽).表信息区.行信息区.块空闲区.行数据区组成,其中ITL用来记录在数据块发生的所有 ...

  6. 在cmd中启动tomcat

    E:\Documents and Settings\topicis>h: H:\>cd tomcat-test H:\tomcat-test>cd bin H:\tomcat-tes ...

  7. qt客户端程序使用svg图片资源的几种方法

    直接使用svg格式文件资源的情况 1. 直接在UI控件属性面板中选择部分支持icon图标的控件的icon来源,这样图标可以显示 2.给toolbutton添加样式 qproperty-icon: ur ...

  8. python学习方法

    python学习体系 python相关书籍若干本 了解python基础数据类型 熟悉各种类型的操作方法 理解函数与类的概念 练习练习再练习 前期以被动学习为主,把每个知识点都认真的学过去,后期慢慢再把 ...

  9. Tomcat配置多线程和配置数据库连接池

    Tomcat配置多线程和配置数据库连接池 1.  tomcat配置线程池: [root@RD2_AS yanghuihui]# cd /usr/tomcat/conf/ [root@RD2_AS co ...

  10. Java集合中removeIf的使用

    在JDK1.8中,Collection以及其子类新加入了removeIf方法,作用是按照一定规则过滤集合中的元素.这里给读者展示removeIf的用法.首先设想一个场景,你是公司某个岗位的HR,收到了 ...