1.对象创建型模式

1.4          Protoype模式

1.4.1需求

通过拷贝原形对象创建新的对象。

1.4.2结构


•P r o t o t y p e(Gr a p h i c)

— 声明一个克隆自身的接口。

•C o n c r e t e P r o t o t y p e(S t a ff、W h o l e N o t e、H a l fN o t e)

— 实现一个克隆自身的操作。

•  C l i e n t(G r a p h i c To o l)

— 让一个原型克隆自身从而创建一个新的对象。

1.4.3样例-C++

//Prototype.h

#ifndef _PROTOTYPE_H_

#define _PROTOTYPE_H_

class Prototype

{

public:

                virtual ~Prototype();

                virtual Prototype*Clone()const = 0;

protected:

                Prototype();

private:

};

class ConcretePrototype:public Prototype

{

public:

                ConcretePrototype();

                ConcretePrototype(const  ConcretePrototype& cp);

                ~ConcretePrototype();

                Prototype* Clone() const;

protected:

private:

};

#endif //~_PROTOTYPE_H_

代码片断2:Prototype.cpp

//Prototype.cpp

#include"Prototype.h"

#include<iostream>

using namespace std;

Prototype::Prototype()

{

}

Prototype::~Prototype()

{

}

Prototype* Prototype::Clone() const

{

                return 0;

}

ConcretePrototype::ConcretePrototype()

{

}

ConcretePrototype::~ConcretePrototype()

{

}

ConcretePrototype::ConcretePrototype(const  ConcretePrototype& cp)

{

                cout<<"ConcretePrototype copy..."<<endl;

}

Prototype* ConcretePrototype::Clone() const

{

                return newConcretePrototype(*this);

}

//main.cpp

#include"Prototype.h"

#include<iostream>

using namespace std;

int main(int argc,char*argv[])

{

                Prototype* p= newConcretePrototype();

                Prototype* p1=p->Clone();

                return 0;

}

注:这里仅仅是说明概念,没有涉及C++常见的深度拷贝问题.

1.4.4 样例-JAVA

在Java中,原型模式能够非常easy地实现,仅仅要实现Cloneable这个标识性的接口,再覆盖该接口中的clone()方法,就可以“克隆”该实现类的不论什么一个对象。

class ConcretePrototype02 implements Cloneable{ 

  private String name; 

  private ArrayList<String> nameList = new ArrayList<String>(); 



  public ConcretePrototype02(String name) { 

    this.name = name; 

    this.nameList.add(this.name); 

  } 

  //加入nameList中的对象 

  public void setName(String name) { 

    this.nameList.add(name); 

  } 

    

  public ArrayList<String> getNameList() { 

    return this.nameList; 

  } 

    

  //覆盖Object基类中的clone()方法,并扩大该方法的訪问权限,详细化返回本类型 

  public ConcretePrototype02 clone() { 

    ConcretePrototype02self = null; 

    try { 

      self= (ConcretePrototype02) super.clone(); 

      //下面这句是实现深拷贝的关键 

//      self.nameList =(ArrayList<String>) this.nameList.clone(); 

    } catch (CloneNotSupportedException e) { 

      e.printStackTrace(); 

    } 

    return self; 

  } 





//測试类 

public class Client { 

  public static void main(String[] args) { 

    ConcretePrototype02prototype02 = new ConcretePrototype02("蚂蚁 ..."); 

    System.out.println(prototype02.getNameList()); 

     

    //通过clone获得一个拷贝 

    ConcretePrototype02fromClone02 = prototype02.clone(); 

    fromClone02.setName("小蚂蚁 ..."); 

    System.out.println(fromClone02.getNameList()); 

    System.out.println(prototype02.getNameList()); 

  } 

}

測试结果:

拷贝之前的原型: [蚂蚁 ...]

拷贝得到的对象: [蚂蚁 ..., 小蚂蚁 ...]

拷贝之后的原型: [蚂蚁 ..., 小蚂蚁 ...]

发现拷贝之后原来的对象持有的ArrayList<String>类型的nameList引用会随着拷贝得到的fromClone对象运行了setName()方法而改变。这不是我们想要的结果,由于这意味着原型以及拷贝得到的对象共享同一个引用变量,这是线程不安全的。当我们去掉   
上面clone()方法中被凝视的语句之后再測试,得到结果例如以下:

拷贝之前的原型: [蚂蚁 ...]

拷贝得到的对象: [蚂蚁 ..., 小蚂蚁 ...]

拷贝之后的原型: [蚂蚁 ...]

在Java中使用原型模式Prototype是相当简单的,仅仅要记住几点注意点,就能够方便地实现该模式了。

因为使用clone()方法来拷贝一个对象是从内存二进制流中进行IO读写。所以拷贝得到一个对象是不会运行该对象所相应类的构造函数的。

总结例如以下:

1、构造函数不会被运行。

2、类的成员变量中若有引用类型的变量(数组也是一种对象)。默认的clone()并不会对其进行拷贝,需自行提供深拷贝;

设计模式(4)-对象创建型模式-Prototype模式的更多相关文章

  1. 设计模式(3)-对象创建型模式-Abstract Factory模式

    1.对象创建型模式 1.3           Abstract Factory模式 1.3.1 需求 在下面情况能够使用Abstract Factory模式: •  一个系统要独立于它的产品的创建. ...

  2. JAVA设计模式 2【创建型】原型模式的理解与使用

    在本节中,我们将学习和使用原型模式:这一节学习的原型模式也是创建型 模式的其中之一.再次复习一下:创建型 模式就是描述如何去更好的创建一个对象. 我们都知道,在JAVA 语言中.使用new 关键字创建 ...

  3. 【创建型】Prototype模式

    原型模式主要是用原型实例指定创建原型对象的种类,并且通过拷贝原型创建新对象.最简单的理解就是克隆.就如cocos2d-x中的 class Clonable::clone();该模式的主要目的是可以在运 ...

  4. Java经典设计模式之五大创建型模式

    转载: Java经典设计模式之五大创建型模式 一.概况 总体来说设计模式分为三大类: (1)创建型模式,共五种:工厂方法模式.抽象工厂模式.单例模式.建造者模式.原型模式. (2)结构型模式,共七种: ...

  5. [C#]设计模式-抽象工厂-创建型模式

    介绍了简单工厂与工厂方法之后,现在我们来看一下工厂三兄弟的最后一个 -- 抽象工厂. 那什么是抽象工厂呢? 抽象工厂模式(Abstract Factory Pattern):提供一个创建一系列相关或相 ...

  6. Java设计模式——单例模式(创建型模式)

    概述   单例模式保证对于每一个类加载器,一个类仅有一个实例并且提供全局的访问.其是一种对象创建型模式.对于单例模式主要适用以下几个场景: 系统只需要一个实例对象,如提供一个唯一的序列号生成器 客户调 ...

  7. php开发面试题---创建型设计模式1(创建型设计模式有哪几种)

    php开发面试题---创建型设计模式1(创建型设计模式有哪几种) 一.总结 一句话总结: 共五种:(简单工厂模式).工厂方法模式.抽象工厂模式.单例模式.建造者模式.原型模式. 1.学设计模式最好的方 ...

  8. ProtoType(原型)-对象创建型模式

    1.意图 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象. 2.动机 通过拷贝或者“克隆”一个类的实例来创建新的实例. 3.适用性 当一个系统应该独立于它的产品创建.构成和表示时,要使 ...

  9. NET设计模式 第二部分 创建型模式(5):原型模式(Prototype Pattern)

    原型模式(Prototype Pattern) ——.NET设计模式系列之六 Terrylee,2006年1月 概述 在软件系统中,有时候面临的产品类是动态变化的,而且这个产品类具有一定的等级结构.这 ...

随机推荐

  1. Xcode6使用storyboard在TabBarController上建立三个以上Item

    在Xcode5上做以上的操作没有问题,这次是要在Xcode6上实现之,特记录以备用. 首先新建一个storyboard文件.取名Custom.storyboard.拖动菜单添加一个TabBarComt ...

  2. JAVA编程相关:eclipse如何导入已有工程

    eclipse使用过程中,经常会遇到导入外部eclispe工程的情况,导入外部eclipse也就是将已有的eclipse工程导入到eclipse中,那么如何导入外部工程呢?下面为大家分享导入已有ecl ...

  3. CentOS的ssh sftp配置及权限设置(流程相当完整)(关闭了SElinux才能上传了)

    从技术角度来分析,几个要求: 1.从安全方面看,sftp会更安全一点 2.线上服务器提供在线服务,对用户需要控制,只能让用户在自己的home目录下活动 3.用户只能使用sftp,不能ssh到机器进行操 ...

  4. Buenos Aires和Rio de Janeiro怎么发音?

    Buenos Aires和Rio de Janeiro怎么发音?_百度知道     Buenos Aires和Rio de Janeiro怎么发音?    2009-09-25 08:58 zd029 ...

  5. Java--Eclipse关联Java源码

    打开Eclipse,Window->Preferences->Java 点Edit按钮后弹出: 点Source Attachment后弹出: 选择Java安装路径下的src.zip文件即可 ...

  6. Android实时获取音量(单位:分贝)

    基础知识 度量声音强度,大家最熟悉的单位就是分贝(decibel,缩写为dB).这是一个无纲量的相对单位,计算公式如下: 分子是测量值的声压,分母是参考值的声压(20微帕,人类所能听到的最小声压).因 ...

  7. 网页WEB打印控件

    网页WEB打印控件制作 在WEB系统中,打印的确是比较烦人的问题,如果我们能制作一个属于自己的自定义的打印插件,那么我们在后续自定义打印的时候能随心所欲的控制打印,这样的效果对于程序员来说是非常开心的 ...

  8. FMX对象释放

    今天盒子中有朋友遇到对象释放的问题,原文在这里,他的实现大意是建立一个TmyLayout = class(TLayout),然后在这个类中画线,Form对象调用实例化这个类来画线,然后释放掉这个对象, ...

  9. hibernate解决oracle的id自增?

    以前做SSH项目时,涉及到的数据库是mySQL,只需将bean的配置文件id设为native 就可以实现表id的自增. 现在用到了Oracle,当然知道这样是不行的啦,那么用序列自增? 我在网络上搜索 ...

  10. Duanxx的C++学习: 使用类没有被定义 原因及解决方法

    今天,随着C++写的神经网络算法.我发现了一个很令人费解的问题,下面的描述一般地描述,例如: 我有两个类ClassA和ClassB,它们分别有成员变量a.b; ClassA有一个函数是这种:Funct ...