定义:

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

结构:(书中图,侵删)

一个申明克隆自己的接口
若干具体的需要克隆自己的类
 
这个结构很简单,而且在Java中那个接口是不需要自己写的。
Java类库中有现成的Cloneable接口,这只是一个标记接口,里面没有任何方法,但如果不加这个标记,会抛CloneNotSupportedException异常。
真正的clone()方法继承自Object类,但是必须要重写。
这里的clone()方法是浅克隆。

这里需要先解释一下深克隆和浅克隆的区别:
克隆,顾名思义,就是复制一个一模一样的。
java clone()方法的操作方式就是,开辟一块和当前对象一样的空间,然后把内容原样拷贝过去。
这导致的结果就是:
基础类型(char、int、long等)会是直接的值拷贝过去。
但是像对象这些拷贝过去的就只是引用,导致,所有克隆出来的孩子里的引用类型都指向同一个地方,而不是每人新建了一份。
这就是浅克隆。
深克隆就是把上述指向同一个地方的引用换成了每个人都指向一个新的地方,里面的值依旧是一样的。(下面的例子会使用深克隆)

实例:

一个歌手,他有基本信息:姓名、年龄;
热门歌曲信息:歌名、发行时间。
歌手类:
package designpattern.prototype;

public class Singer implements Cloneable {
String name;
int age;
HotMusic hotMusic; public Singer(String name, int age, HotMusic hotMusic) {
super();
this.name = name;
this.age = age;
this.hotMusic = hotMusic;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public int getAge() {
return age;
} public void setAge(int age) {
this.age = age;
} public HotMusic getHotMusic() {
return hotMusic;
} public void setHotMusic(HotMusic hotMusic) {
this.hotMusic = hotMusic;
} @Override
protected Object clone() throws CloneNotSupportedException {
Singer singerClone = (Singer) super.clone();
singerClone.hotMusic = (HotMusic) hotMusic.clone();// 这一句,下面解释
return singerClone;
} @Override
public String toString() {
return "Singer [name=" + name + ", age=" + age + ", hotMusic=" + hotMusic + "]";
} }
歌曲信息类:
package designpattern.prototype;

public class HotMusic implements Cloneable {
String name;
String date; public HotMusic(String name, String date) {
super();
this.name = name;
this.date = date;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public String getDate() {
return date;
} public void setDate(String date) {
this.date = date;
} @Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
} @Override
public String toString() {
return "HotMusic [name=" + name + ", date=" + date + "]";
} }
客户端:

package designpattern.prototype;

public class Client {
public static void main(String[] args) {
Singer singer1 = new Singer("周杰伦", 40, new HotMusic("告白气球", "2016"));
System.out.println(singer1); try {
Singer singer2 = (Singer) singer1.clone();
singer2.hotMusic.setName("等你下课");
singer2.hotMusic.setDate("2018");
System.out.println("========================================================");
System.out.println(singer1);
System.out.println(singer2);
} catch (CloneNotSupportedException e) {
e.printStackTrace();
} } }
输出结果:(深克隆)
Singer [name=周杰伦, age=40, hotMusic=HotMusic [name=告白气球, date=2016]]
========================================================
Singer [name=周杰伦, age=40, hotMusic=HotMusic [name=告白气球, date=2016]]
Singer [name=周杰伦, age=40, hotMusic=HotMusic [name=等你下课, date=2018]]
如果把歌手类中注释的那一句去掉,结果会是:(浅克隆)
Singer [name=周杰伦, age=40, hotMusic=HotMusic [name=告白气球, date=2016]]
========================================================
Singer [name=周杰伦, age=40, hotMusic=HotMusic [name=等你下课, date=2018]]
Singer [name=周杰伦, age=40, hotMusic=HotMusic [name=等你下课, date=2018]]

总结:

其实之前我从来都没有用过这个方法,之前看到文中说,要创建多个一模一样的对象,直接循环new不就得了?还搞那么麻烦。
看到书中的话对我有很大的启发,我就直接整理一下敲上来了:
每new一次,都要执行一次构造函数,如果构造函数的执行时间很长,那么多次执行会很低效。
一般在初始化的信息不发生变化的情况下,克隆是最好的办法。这既隐藏了对象的创建细节,又对性能是大大的提高。
结合我上面说的,克隆是直接复制内存的,显然比执行构造方法高效的多。

设计模式 | 原型模式(prototype)的更多相关文章

  1. PHP设计模式 原型模式(Prototype)

    定义 和工厂模式类似,用来创建对象.但实现机制不同,原型模式是先创建一个对象,采用clone的方式进行新对象的创建. 场景 大对象的创建. 优点 1.可以在运行时刻增加和删除产品 2.可以改变值或结构 ...

  2. [工作中的设计模式]原型模式prototype

    一.模式解析 提起prototype,最近看多了js相关的内容,第一印象首先是js的原型 var Person=function(name){ this.name=name; } Person.pro ...

  3. C#设计模式——原型模式(Prototype Pattern)

    一.概述 在软件开发中,经常会碰上某些对象,其创建的过程比较复杂,而且随着需求的变化,其创建过程也会发生剧烈的变化,但他们的接口却能比较稳定.对这类对象的创建,我们应该遵循依赖倒置原则,即抽象不应该依 ...

  4. 设计模式-原型模式(Prototype)

    场景分析: 前面我们提到,交易对象Trade,还有继承他的债券交易BondTrade.期货交易FutureTrade. 现在有一个需求,需要提供方法将交易拆分成多笔小交易. 代码如下(如果没有clon ...

  5. 设计模式——原型模式(Prototype Pattern)

    原型模式:用原型实例制定创建对象的种类,并且通过拷贝这些原型创建新的对象. UML 图: 原型类: package com.cnblog.clarck; /** * 原型类 * * @author c ...

  6. 大话设计模式--原型模式 Prototype -- C++实现

    1. 原型模式: 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象... 注意: 拷贝的时候是浅拷贝 还是 深拷贝, 来考虑是否需要重写拷贝构造函数. 关键在于: virtual Pro ...

  7. 设计模式——原型模式(Prototype)

    用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象.——DP UML类图 模式说明 如果把在一张纸上手写一篇简历的过程看成是类的实例化过程,那么通过原型模式创建对象的过程就是拿着这张纸到复印 ...

  8. 设计模式--原型模式Prototype(创建型)

    一.原型模式 用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象.原型模式实现的关键就是实现Clone函数,还需要实现深拷贝. 二.UML类图 三.例子 //父类 class Resume ...

  9. 谈谈设计模式~原型模式(Prototype)

    返回目录 原型模式是创建型模式的一种,其特点在于通过“复制”一个已经存在的实例来返回新的实例(clone),而不是新建(new)实例.被复制的实例就是我们所称的“原型”,这个原型是可定制的. 原型模式 ...

  10. Net设计模式实例之原型模式( Prototype Pattern)

    一.原型模式简介(Brief Introduction) 原型模式(Prototype Pattern):用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象. Specify the kin ...

随机推荐

  1. 剑指Offer_编程题之二维数组中的查找

    题目描述 在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数.

  2. Linux时间子系统之(十五):clocksource

    专题文档汇总目录 Notes:clocksource基本概念,struct clocksource详解:注册和注销clocksource:内核如何选取clocksource:clocksource相关 ...

  3. 豆瓣API

    Api V2 索引 图书Api V2 电影Api V2 音乐Api V2 同城Api V2 广播Api V2 用户Api V2 日记Api V2 相册Api V2 线上活动Api V2 论坛Api V ...

  4. Spring Boot 定制URL匹配规则的方法

    事情的起源:有人问我,说编写了一个/hello访问路径,但是吧,不管是输入/hello还是/hello.html,还是/hello.xxx都能进行访问.当时我还以为他对代码进行处理了,后来发现不是,后 ...

  5. Git协作流程

    Git 作为一个源码管理系统,不可避免涉及到多人协作. 协作必须有一个规范的流程,让大家有效地合作,使得项目井井有条地发展下去."协作流程"在英语里,叫做"workflo ...

  6. 超实用的JavaScript代码段 Item5 --图片滑动效果实现

    先上图 鼠标滑过那张图,显示完整的哪张图,移除则复位: 简单的CSS加JS操作DOM实现: <!doctype html> <html> <head> <me ...

  7. git回退到某个历史版本

    1. 使用git log命令查看所有的历史版本,获取某个历史版本的id,假设查到历史版本的id是139dcfaa558e3276b30b6b2e5cbbb9c00bbdca96. 2. git res ...

  8. scrapy顺序执行多个爬虫

    # -*- coding:utf-8 -*- from scrapy import cmdline from scrapy.cmdline import execute import sys,time ...

  9. SpringCloud实战8-Bus消息总线

    好了现在我们接着上一篇的随笔,继续来讲.上一篇我们讲到,我们如果要去更新所有微服务的配置,在不重启的情况下去更新配置,只能依靠spring cloud config了,但是,是我们要一个服务一个服务的 ...

  10. [HAOI2008]移动玩具 状压

    发现自己只会打状压了. 233333 不需要考虑是否会被挡,所以直接dp #include<cstdio> #include<cstring> #include<iost ...