`
guafei
  • 浏览: 328212 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

原型模式Prototype(深拷贝)

阅读更多
1、定义:原型模式就是通过一个原型对象来表明要创建的对象类型,然后用复制这个对象的方法来创建更痛类型的对象。
2、原理:有两部分组成,抽象原型和具体原型。
3、使用时机:系统需要 创建吃的对象是动态加载的,而且产品具有一定层次时,可以考虑使用原型模式。
1>当要实例化的类是在运行时刻指定时,例如,通过动态装载;
2>或者为了避免创建一个与产品类层次平行的工厂类层次时;
3>或者当一个类的实例只能有几个不同状态组合中的一种时。
4>建立相应数目的原型并克隆它们可能比每次用合适的状态手工实例化该类更方便一些。
4、效果:
1>可以再运行时刻增加和删除产品。
2>可以通过改变值来指定产品。
3>可以通过改变结构来指定新对象。
4>减少子类的构造
5>可以用类动态配置应用。
5、实现:
1>使用一个原型管理器
2>实现克隆操作(浅拷贝和深拷贝)
3>初始化克隆对象。
6、使用原型模式的意图:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
7、解决的问题:
比如有一个对象,在某一时刻该对象中已经包含了一些有效的值,此时可能会需要一个和该对象完全相同的新对象,并且此后对新对象的任何改动都不会影响到原来对象中的值,也就是说新对象与原来的对象是两个独立的对象,但新对象的初始值是由原来的对象确定的。
Clone:
赋值创建对象:
1>java中赋值创建对象是可以实现对象的重用的,但是新对象和原对象是同一个引用;如果修改其中的一个对象的值,则另外的一个对象也会发生改变。
2>使用clone方法会返回对象的一个拷贝,这样一来,如果修改一个对象的值,则另外的对象不会发生改变的。

原型模式UML图:


请注意,在 这边Cloneable并非指Java中的java.lang.Cloneable,而是指支持原型复制 的对象,必须实作之公开协议。

不 同的语言可能提供不同程 度支持之对象复制技术,以Java而言,java.lang.Object本身即定义有clone()方法,因此所有的对象 基本上 皆具自我复制之能力,不 过真正要让对象支持复制,则对象必须实作java.lang.Cloneable这个标示接口(Tag interface)。

原型模式浅拷贝与原型模式深度拷贝:
看看这样一个示例:有个类(DogClone)实现了Java的Cloneable接口,也实现了Object的clone()方法,它持有另一个 没有实现Cloneable接口并且没有复写Object的clone()方法的引用(Dog)。如果Dog同时实现了clone()方法也实现了 Cloneable接口,在对DogClone做科隆操作的时候会不会影响dog的值呢?

package org.bestupon.prototype.copy;
/**
* 同实现了克隆方法的类和实现克隆方法的类做比较
* @author bestupon
* 浅拷贝Dog
*/
public class Dog {
/**
* 狗腿条数
*/
public int legCounts;

public Dog(int legCounts) {
this.legCounts = legCounts;
}
/**
* 改变狗的腿数量
*/
public void changeLegCounts(){
this.legCounts *=2;
}
public String toString () {
return Integer.toString(this.legCounts);
}
}

package org.bestupon.prototype.clone;
/**
* 该类是没有实现克隆方法的类和实现克隆方法的类做比较
* @author bestupon
* 深度拷贝用例
*/
public class Dog implements Cloneable{
/**
* 狗腿条数
*/
public int legCounts;

public Dog(int legCounts) {
this.legCounts = legCounts;
}
/**
* 改变狗的腿数量
*/
public void changeLegCounts(){
this.legCounts *=2;
}

@Override
public Dog clone() throws CloneNotSupportedException {
return (Dog)super.clone();
}
public String toString () {
return Integer.toString(this.legCounts);
}
}
package org.bestupon.prototype.copy;

public class DogClone implements Cloneable {
/**
* 狗腿条数
*/
public int legCounts;
/**
* 初始化一个狗
*/
Dog dog = new Dog(4);
@Override
protected DogClone clone() throws CloneNotSupportedException {
return (DogClone)super.clone();
}

}

<span style="white-space: normal;">&nbsp;<span style="white-space: pre;">package org.bestupon.prototype.copy;</span></span>
/** 浅拷贝
* @author bestupon
*
*/
public class Client {
public static void main(String args []) throws CloneNotSupportedException {
DogClone dogClone = new DogClone();
dogClone.legCounts = 3;
System.out.println("原来的克隆狗腿数量:"+dogClone.legCounts);
System.out.println("原来的普通狗腿的数量:"+dogClone.dog);//Dog的toString方法返回的值。

DogClone dogClone1 = (DogClone)dogClone.clone();
dogClone1.legCounts=2 ;

Dog dog = dogClone1.dog;
dog.changeLegCounts();
System.out.println("克隆后原来狗腿数量:"+dogClone.legCounts);
/**
  * 出现的结果是:8
  * 原因很简单就是dog是一个引用,改变一个对象的话,会改变另一个对象。
  */
System.out.println("克隆后原来普通狗的数量:"+ dogClone.dog);
System.out.println("克隆后克隆狗腿的数量:"+ dogClone1.legCounts);
/**
  *改变源:改变了自身dogClone.dog,影像了对象dogClone.dog 的值,
  */
System.out.println("克隆后普通狗的数量:"+ dogClone1.dog);

}
}

两次运行结果:

没有实现Cloneable接口和clone()方法结果:

Java代码
原来的克隆狗腿数量:3
原来的普通狗腿的数量:4
克隆后原来狗腿数量:3
克隆后原来普通狗的数量:8
克隆后克隆狗腿的数量:2
克隆后普通狗的数量:8

实现了Cloneable接口和clone()方法结果:

Java代码

原来的克隆狗腿数量:3
原来的普通狗腿的数量:4
克隆后原来狗腿数量:3
克隆后原来普通狗的数量:4
克隆后克隆狗腿的数量:2
克隆后普通狗的数量:8

同样的客户端为什么会有不同的结果呢?这就是所谓的浅拷贝和深拷贝的为题.

分析:
浅拷贝: DogClone类中的legCounts属性被科隆了,因为对科隆后的对象进行修改时,没有改变原来对象的值,其原因是实现了接口和方法,而DogClone,Dog对象 dog没有被科隆,而在修改科隆后的对象时,会改变原来对象的值。
如果要是都实现了接口和方法,就实现了深度科隆,不会影响远对象的值。

应用:
不是所有的对象都是能实现深度科隆的,例如:StringBuffer就没有重载Clone()方法,而且StringBuffer还是一个final类,所以其不能自动实现深度科隆。

在Spring中.深度科隆是应用广泛的。在实体模型上面有这样一个注 解:@Component("lawsuitArchive") @scope("prototype"),表明在别的地方应用的时候,是引用其原型,同时Entity也要实现Cloneable接口和复写 clone()方法。因为原型在初始化的时候就已经创建了一部分有价值的东西,减少容器的压力,而在别的地方,例如action中引用该对象的时候,直接 可以使用@Resource(name="lawsuitArchive")引用对象,Spring会自动的装配好你想要的对象。

有源码
分享到:
评论

相关推荐

    java设计模式【之】原型模式、深拷贝与浅拷贝【源码】【场景:克隆羊】

    java设计模式【之】原型模式、深拷贝与浅拷贝【源码】【场景:克隆羊】 * 原型模式(Prototype) * 实现方式: * 需要被克隆的 class类, 重写Object中的clone()方法,并实现Cloneable接口(否则报错 ...

    原型设计模式prototype

    3. **性能优化**:对于深拷贝的情况,原型模式可以比直接构造新对象更快,特别是当对象结构复杂时。 ### 源码实现 在Java中,我们可以创建一个原型接口: ```java public interface Prototype { Prototype clone...

    设计模式 创建型模式 Prototype模式(原型)

    原型模式中的拷贝分为“浅拷贝”和“深拷贝”: 浅拷贝:对值类型的成员变量进行值的复制,对引用类型的成员变量只复制引用,不复制引用的对象。 深拷贝:对值类型的成员变量进行值的复制,对引用类型的成员变量...

    创建型模式之原型模式(Prototype Pattern)

    **原型模式(Prototype Pattern)详解** 在软件设计中,原型模式是一种创建型设计模式,它提供了一种通过复制已有对象来创建新对象的方式,避免了重复的构造过程,提高了代码的效率和可维护性。原型模式的核心思想...

    原型模式(Prototype)

    在Java、C#等面向对象编程语言中,原型模式可以通过实现克隆接口或使用深拷贝和浅拷贝来实现。 ### 原理和组件 1. **原型(Prototype)**:这是模式的核心,它定义了接口用于复制自己。原型对象通常是具体的类,实现...

    原型模式(ProtoType)C#应用案例

    原型模式(Prototype)是一种软件设计模式,主要用于简化创建对象的过程,尤其当对象的构造过程复杂时。在C#中,我们可以利用接口或者继承来实现这一模式。本案例将深入探讨如何在C#环境中运用原型模式。 首先,...

    原型模式 Prototype Pattern

    ### 原型模式 Prototype Pattern #### 概述 原型模式是一种创建型设计模式,它允许用户通过复制现有的实例来创建新的对象,而不是通过传统的构造器来创建对象。这种模式适用于那些创建对象的成本较高,或者当对象...

    设计模式C++学习之原型模式(Prototype)

    - **深拷贝与浅拷贝**:不正确地处理深拷贝和浅拷贝可能导致意料之外的结果,尤其是在含有指针成员的情况下。 在Demo20_Prototype中,我们可以看到具体的原型模式实现示例,它可能包含了不同类型的原型对象以及如何...

    Prototype模式

    **原型模式(Prototype Pattern)**是一种创建型设计模式,它提供了一种通过复制已有对象来创建新对象的方式,而不是通过构造函数。在某些情况下,当创建新对象的成本非常高时(例如,对象需要大量的初始化操作或者从...

    设计模式之原型模式Java实现和类设计图

    2. **深拷贝与浅拷贝**: 在原型模式中,我们通常关心的是对象的拷贝方式。浅拷贝只复制对象的引用,而深拷贝会复制对象以及其引用的所有子对象。在Java中,`clone()`方法默认执行的是浅拷贝,但可以通过实现自定义的...

    Prototype Pattern原型模式

    **原型模式(Prototype Pattern)**是一种基于克隆的创建型设计模式,它的主要目的是为了提高创建新对象的效率,特别是当创建新对象的过程复杂或者资源消耗较大时。在原型模式中,一个已经创建的对象(称为原型)被...

    设计模式之原型模式

    3. **深拷贝与浅拷贝**:原型模式中的拷贝分为两种类型——深拷贝和浅拷贝。深拷贝会创建原始对象的所有属性的新副本,包括引用类型。而浅拷贝只复制对象本身,不复制引用的对象。 ### 实现原型模式的步骤 1. 定义...

    原型模式实践代码

    在Text0313文件中,可能包含了实现上述原型模式的完整Java代码示例,可能还涉及了如何处理深拷贝、异常处理以及如何在不同场景下使用原型模式的细节。 总的来说,原型模式是一种有效的优化性能和提高代码复用性的...

    iOS设计模式之原型模式

    此外,原型模式在处理深拷贝和浅拷贝时也有所区别。深拷贝会创建一个新的对象,包括所有子对象的完整副本,而浅拷贝则只复制对象本身,子对象的引用仍指向原对象。在实现NSCopying时,需要注意是否需要进行深拷贝,...

    通过java实现原型模式(Prototype Pattern).rar

    在Java中,原型模式通常通过实现一个原型接口或抽象类,并在具体类中提供克隆方法来实现。Java中有一个内置的Cloneable接口和Object类的clone()方法,它们可以被用来实现对象的克隆。但是,直接使用clone()方法需要...

    prototype原型模式

    - `prototype.pro` 是Qt项目文件,用于编译和构建原型模式的示例。 - `readme.txt` 可能是项目说明文件,包含关于如何运行和理解代码的指导。 - `mainwindow.ui` 是Qt Designer生成的用户界面描述文件,描述了GUI的...

    实验六:原型模式.rar

    在这个实验六:“原型模式.rar”中,我们将深入理解并实践如何在Java中实现原型模式。 首先,原型模式的核心思想是通过拷贝已有对象来创建新对象,而不是从零开始创建。这种模式在处理复杂对象或者需要大量初始化...

    设计模式——原型模式

    原型模式(Prototype Pattern)是一种创建型设计模式,它允许我们通过复制现有的对象来创建新对象,而无需知道具体创建过程的细节。这种模式的核心在于,它提供了一种对象克隆的简便方法,使得对象的创建过程对用户...

    PHP设计模式(四)原型模式Prototype实例详解【创建型】

    原型模式(Prototype Pattern)属于创建型设计模式的一种,它允许我们创建具有相同特性的对象,而不必直接通过构造函数来实例化对象。原型模式在PHP中主要通过clone关键字来实现,当我们需要一个与某个已存在对象...

    设计模式专题之(五)原型模式---设计模式原型模式示例代码(python--c++)

    在Python中,实现原型模式相对简单,因为Python提供了内置的`copy`模块,可以方便地实现浅复制和深复制。在`Prototype.py`文件中,我们可能会看到以下代码结构: ```python class Prototype: def __init__(self, ...

Global site tag (gtag.js) - Google Analytics