设计模式学习之原型模式(Prototype,创建型模式)(5)
通过序列化的方式实现深拷贝
[Serializable]
public class Person:ICloneable
{
public string Name { get; set; }
public int Age { get; set; }
public List<Friend> FriendList { get; set; }
public object Clone()
{
MemoryStream memoryStream = new MemoryStream();
BinaryFormatter formatter = new BinaryFormatter();
formatter.Serialize(memoryStream, this);
memoryStream.Position = ;
Person p = (Person)formatter.Deserialize(memoryStream);
return p;
}
}
[Serializable]
public class Friend
{
public string Name { get; set; }
public int Age { get; set; }
}
在开发中如果我们希望快速的创建一个对象,并且该对象和原有的对象拥有相同的数据,并且和原有的对象不相干,那么我们就可以这样做
第一步:
假如我需要快速创建一个Person对象,然后和某个Person对象相同,如果我们我们只需要Person对象中的属性不引用其他数据信息,可以使用浅拷贝;
如果我们需要Person对象中所有的信息,包括引用的数据信息,可以使用深拷贝
第二步:
在Person类中实现Cloneable接口,重写clone()方法,如果是浅拷贝,只需要直接调用父类的clone()方法就行,如果是深拷贝,需要在clone()方法中重新开辟引用字段所需的内存
代码如下:
Person.java
package com.designpattern.prototype; import java.util.ArrayList;
import java.util.List; public class Person implements Cloneable {
private String name;
private int age; //朋友
private List<String> friends; public List<String> getFriends() {
return friends;
}
public void setFriends(List<String> friends) {
this.friends = friends;
}
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;
} /**
* 实现浅拷贝
*/
// protected Person clone(){
//
// try {
// return (Person)super.clone();
// } catch (CloneNotSupportedException e) {
// e.printStackTrace();
// return null;
// }
//
// } /**
* 实现深拷贝
*/
protected Person clone(){ try {
List<String> newfriends = new ArrayList<String>();
for (String friend : this.getFriends()) {
newfriends.add(friend);
}
Person person = (Person)super.clone();
person.setFriends(newfriends);
return person;
} catch (CloneNotSupportedException e) {
e.printStackTrace();
return null;
} }
}
MainClass.java
package com.designpattern.prototype; import java.util.ArrayList;
import java.util.List; public class MainClass { public static void main(String[] args) {
//假如我需要快速创建一个Person对象,然后和某个Person对象相同,如果我们我们只需要Person对象中的属性不引用其他数据信息,可以使用浅拷贝
//如果我们需要Person对象中所有的信息,包括引用的数据信息,可以使用深拷贝
/*
* 浅拷贝
*/
// Person person = new Person();
// person.setName("jack");
// person.setAge(18);
//
// Person person2 = person.clone();//相当于重新开辟一块内存空间,和person互不干扰
// person2.setName("jack1");
//
// System.out.println(person.getName());
// System.out.println(person2.getName()); Person person = new Person();
person.setName("jack");
person.setAge();
List<String> friends = new ArrayList<String>();
friends.add("p1");
friends.add("p2");
person.setFriends(friends); Person person2 = person.clone();
person2.setName("jack1");
friends.add("p3");//person 引用friends,friends改变,person的friends就会改变,如果用浅拷贝,person2也会跟着改变
//如果用深拷贝,person2不会跟着改变,因为person2的friends和person的friends没有指向同一块内存 System.out.println(person.getName());
System.out.println(person2.getName());
System.out.println(person.getFriends());
System.out.println(person2.getFriends());
} }
一、什么是原型模式
Prototype模式是一种对象创建型模式,它采取复制原型对象的方法来创建对象的实例。使用Prototype模式创建的实例,具有与原型一样的数据。
二、原型模式的特点
1. 由原型对象自身创建目标对象。也就是说,对象创建这一动作发自原型对象本身。
2.目标对象是原型对象的一个克隆。也就是说,通过Prototype模式创建的对象,不仅仅与原型对象具有相同的结构,还与原型对象具有相同的值。
3.根据对象克隆深度层次的不同,有浅度克隆与深度克隆。
三、原型模式应用场景
- 在创建对象的时候,我们不只是希望被创建的对象继承其基类的基本结构,还希望继承原型对象的数据。
- 希望对目标对象的修改不影响既有的原型对象(深度克隆的时候可以完全互不影响)。
- 隐藏克隆操作的细节。很多时候,对对象本身的克隆需要涉及到类本身的数据细节。
.Net Framework源代码中的模式之Prototype(原型模式)
转载地址:http://kb.cnblogs.com/page/68814/
用原型实例指定创建对象的种类,并且通过拷贝这个原型来创建新的对象。
以.NET Framework 2.0 System.Collections中类为例。
System.Collections. ICollection
{
}
System.Collections. ICloneable
{
object Clone();
}
System.Collections. Stack
{
public virtual Object Clone()
{
Stack s = new Stack(_size);
s._size = _size;
Array.Copy(_array, 0, s._array, 0, _size);
s._version = _version;
return s;
}
}
System.Collections. Queue
{
public virtual Object Clone()
{
Queue q = new Queue(_size);
q._size = _size;
int numToCopy = _size;
int firstPart = (_array.Length - _head < numToCopy) ? _array.Length - _head : numToCopy;
Array.Copy(_array, _head, q._array, 0, firstPart);
numToCopy -= firstPart;
if (numToCopy > 0)
Array.Copy(_array, 0, q._array, _array.Length - _head, numToCopy);
q._version = _version;
return q;
}
}
调用代码
{
public static void Main()
{
Stack myStack = new Stack();
myStack.Push("Hello");
myStack.Push("World");
myStack.Push("!");
Stack myStackCopy = (Stack)myStack.Clone();
foreach (string s in myStackCopy)
{
Console.Write(s);
}
Console.WriteLine();
Console.ReadLine();
}
}
在.NET Framework中,可以通过实现ICloneable接口来实现原型模式,ICloneable接口只有一个Clone方法。克隆的实现方法有两种:浅拷贝(shallow copy)与深拷贝(deep copy)。
浅拷贝是指当对象的字段值被拷贝时,字段引用的对象不会被拷贝。例如,如果一个对象有一个指向字符串的字段,并且我们对该对象做了一个浅拷贝,那么两个对象将引用同一个字符串。而深拷贝是对对象实例中字段引用的对象也进行拷贝的一种方式,所以如果一个对象有一个指向字符串的字段,并且我们对该对象做了一个深拷贝的话,我们将创建一个新的对象和一个新的字符串--新对象将引用新字符串。需要注意的是执行深拷贝后,原来的对象和新创建的对象不会共享任何东西;改变一个对象对另外一个对象没有任何影响。
对于值类型,浅拷贝通过赋值等操作直接实现,将对象中的值类型的字段拷贝到新的对象中;深拷贝和浅拷贝相同,通过赋值等操作直接实现,将对象中的值类型的字段拷贝到新的对象中。 对于引用类型,浅拷贝通过MemberwiseClone 方法创建一个浅副本,方法是创建一个新对象,如果字段是值类型的,则对该字段执行逐位复制,如果字段是引用类型,则复制引用原始对象,与原对象引用同一对象;深拷贝拷贝对象应用,也拷贝对象实际内容,也就是创建了一个新的对象,改变新对象不会影响到原始对象的内容。
在下列情况下,应当使用Prototype模式:
- 当一个系统应该独立于它的产品创建,构成和表示时;
- 当要实例化的类是在运行时刻指定时,例如,通过动态装载;
- 为了避免创建一个与产品类层次平行的工厂类层次时;
- 当一个类的实例只能有几个不同状态组合中的一种时。建立相应数目的原型并克隆它们可能比每次用合适的状态手工实例化该类更方便一些。
设计模式学习之原型模式(Prototype,创建型模式)(5)的更多相关文章
- 设计模式学习之单例模式(Singleton,创建型模式)(4)
假如程序中有一个Person类,我的需求就是需要在整个应用程序中只能new一个Person,而且这个Person实例在应用程序中进行共享,那么我们该如何实现呢? 第一步: 新建一个Person类,类中 ...
- 设计模式05: Prototype 原型模式(创建型模式)
Prototype 原型模式(创建型模式) 依赖关系的倒置抽象不应该依赖于实现细节,细节应该依赖于抽象.对所有的设计模式都是这样的. -抽象A直接依赖于实现细节b -抽象A依赖于抽象B,实现细节b依赖 ...
- 原型模式 prototype 创建型 设计模式(七)
原型模式 prototype 意图 用原型实例指定需要创建的对象的类型,然后使用复制这个原型对象的方法创建出更多同类型的对象 显然,原型模式就是给出一个对象,然后克隆一个或者更多个对象 小时候看 ...
- Prototype,创建型模式
读书笔记_探索式测试_混合探索式测试 一.测试场景 1.讲述用户故事 2.描述需求 3.演示产品功能 4.演示集成场景 5.描述设置和安装 6.描述警告和出错情况 二.使用基于场景的探索式测试 1 ...
- 设计模式04: Factory Methord 工厂方法模式(创建型模式)
Factory Methord 工厂方法模式(创建型模式) 从耦合关系谈起耦合关系直接决定着软件面对变化时的行为 -模块与模块之间的紧耦合使得软件面对变化时,相关的模块都要随之变更 -模块与模块之间的 ...
- 设计模式03: Builder 生成器模式(创建型模式)
Builder生成器模式(创建型模式) Builder模式缘起假设创建游戏中的一个房屋House设施,该房屋的构建由几个部分组成,且各个部分富于变化.如果使用最直观的设计方法,每个房屋部分的变化,都将 ...
- (转)Java经典设计模式(1):五大创建型模式(附实例和详解)
原文出处: 小宝鸽 一.概况 总体来说设计模式分为三大类: (1)创建型模式,共五种:工厂方法模式.抽象工厂模式.单例模式.建造者模式.原型模式. (2)结构型模式,共七种:适配器模式.装饰器模式.代 ...
- 设计模式01: Singleton 单例模式(创建型模式)
Singleton 单例模式(创建型模式) 动机(Motivation)当进行软件开发是会有这样一种需求:在系统中只有存在一个实例才能确保它们的逻辑正确性.以及良好的效率.这应该是类设计者的责任,而不 ...
- Java设计模式——建造者模式(创建型模式)
概述 建造者模式也称为生成器模式,是一种对象创建型模式,它可以将复杂对象的建造过程抽象出来(抽象类别),使这个抽象过程的不同实现方法可以构造出不同表现(属性)的对象. 建造者模式意在为重叠构造 ...
随机推荐
- PHP开发APP接口----单例模式连接数据库
<?php //单例模式 class Db{ static private $_instance; static private $_connectSource; private $_dbCon ...
- 如何在ECSHOP前台后台中讲版权内容清除
如何在ECSHOP前台后台中讲版权内容清除 作者:河南电脑学校网 点击次数:1065 发布时间:2012-02-02 20:13:58 一.ECSHOP前台显示的页面的版权在下面几个地方修改:(本人不 ...
- 说说Java中的枚举(一)
在实际编程中,往往存在着这样的“数据集”,它们的数值在程序中是稳定的,而且“数据集”中的元素是有限的.例如星期一到星期日七个数据元素组成了一周的“数据集”,春夏秋冬四个数据元素组成了四季的“数据集”. ...
- jquery json ajax
当html中用script包含了不在同一个目录下的js外部文件(主要是为了通用代码的重用)时,这个js文件的 内容就如同在当前html文件中了,写jquery的时候不用考虑路径问题,可以直接引用htm ...
- 使用node.js制作简易爬虫
最近看了些node.js方面的知识,就像拿它来做些什么.因为自己喜欢摄影,经常上蜂鸟网,所以寻思了一下,干脆做个简单的爬虫来扒论坛的帖子. 直接上代码吧. var sys = require(&quo ...
- 让chrome浏览器变成在线编辑器
在大部分人眼里,技术宅给人的印象是沉默寡言,总摸不透他心里想些什么,彼此都保持距离.作为半个程序员,我觉得真正的技术宅大部分时间都在找乐子,鼓捣各种想法,和大部分人的极客心理是一样的,程序员也还爱讲笑 ...
- Zhulina 的高分子刷理论
高分子刷的解析平均场理论有两种表述方式.一个是MWC理论(Macromolecules 1988, 21, 2610-2619),另外一个就是Zhulina和Birshtein这两位俄罗斯老太太的理论 ...
- HDOJ 3555 Bomb
数位DP的DFS写法.... Bomb Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/65536 K (Java/Oth ...
- sql 批量更新
利用update和select进行批量更新 UPDATE Table1 SET categoryId =(SELECT Id FROM Table2 WHERE Table1 .Id=Table2.c ...
- 2015安徽省赛 C.LU的困惑
题目描述 Master LU 非常喜欢数学,现在有个问题:在二维空间上一共有n个点,LU每连接两个点,就会确定一条直线,对应有一个斜率.现在LU把平面内所有点中任意两点连线,得到的斜率放入一个集合中( ...