设计模式之笔记--原型模式(Prototype)
原型模式(Prototype)
定义
原型模式(Prototype),用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
类图
描述
提供一个克隆自身的接口--Clone方法。
应用场景
定义一个学生类,包含一个值类型(int)的Age属性、两个引用类型Name(string)和Course属性。
public class Course
{
public string Name { get; set; }
} public abstract class AbstractStudent
{
public string Name { get; set; }
public int Age { get; set; }
public Course Course { get; set; } public abstract AbstractStudent Clone();
} /// <summary>
/// 浅拷贝
/// </summary>
public class Student : AbstractStudent
{
public override AbstractStudent Clone()
{
Student student = new Student();
student.Name = base.Name;
student.Age = base.Age;
student.Course = base.Course; return student;
}
}
输出:
student : Jim 20 C++
student : Jim 20 C#
student1: Tom 21 C#
student : Jim 20 Java
student1: Tom 21 Java
从打印的结果可以看出,给原对象student拷贝一个新的student1对象并给student1属性赋值之后,原对象student的Age和Name没变,CourseName却变了。原因是拷贝之后,student把student1的Age和Name复制了一份,而student1的Course依然指向student的Course地址,所以,当student1的CourseName改变时,student的CourseName也随之改变,这就是浅拷贝。
但是在实际应用中,往往不希望发生这样的事情,也就是不能因为拷贝对象发生变化而影响到原对象。原因很简单,不能因为Tom选了C#这门课就要求Jim也必须把已经选的C++这门课改成C#。要解决这个问题,就需要拷贝一个全新的对象,即深拷贝。
下面通过序列化和反序列化来创建一个全新的student:
[Serializable]
public class Course
{
public string Name { get; set; }
} [Serializable]
public abstract class AbstractStudent
{
public string Name { get; set; }
public int Age { get; set; }
public Course Course { get; set; } public abstract AbstractStudent Clone();
} [Serializable]
/// <summary>
/// 深拷贝
/// </summary>
public class Student : AbstractStudent
{
public override AbstractStudent Clone()
{
using (Stream objectStream = new MemoryStream())
{
IFormatter formatter = new BinaryFormatter();
formatter.Serialize(objectStream, this);
objectStream.Seek(, SeekOrigin.Begin);
return formatter.Deserialize(objectStream) as Student;
}
}
}
输出:
student : Jim 20 C++
student : Jim 20 C++
student1: Tom 21 C#
student : Jim 20 C++
student1: Tom 21 Java
浅拷贝和深拷贝的区别:
浅拷贝:对值类型和string类型直接拷贝,对引用类型共用同一个指针;两个对象之间存在耦合;
深拷贝:给对象拷贝一个全新的对象,两个对象之间的耦合度为0。
设计模式之笔记--原型模式(Prototype)的更多相关文章
- 设计模式系列之原型模式(Prototype Pattern)——对象的克隆
说明:设计模式系列文章是读刘伟所著<设计模式的艺术之道(软件开发人员内功修炼之道)>一书的阅读笔记.个人感觉这本书讲的不错,有兴趣推荐读一读.详细内容也可以看看此书作者的博客https:/ ...
- Net设计模式实例之原型模式( Prototype Pattern)
一.原型模式简介(Brief Introduction) 原型模式(Prototype Pattern):用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象. Specify the kin ...
- 设计模式 笔记 原型模式 prototype
//---------------------------15/04/07---------------------------- //prototype 原型模式--对象创建型模式 /* 1:意图: ...
- 设计模式学习心得<原型模式 Prototype >
原型模式(Prototype Pattern)是用于创建重复的对象,同时又能保证性能.这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式. 这种模式是实现了一个原型接口,该接口用于创建当 ...
- IOS设计模式浅析之原型模式(Prototype)
原型模式的定义 “使用原型实例指定创建对象的种类,并通过复制这个原型创建新的对象”.最初的定义出现于<设计模式>(Addison-Wesley,1994). 简单来理解就是根据这个原型创建 ...
- 学习笔记——原型模式Prototype
原型模式,简单说就是具有一个克隆方法,外部可以直接使用此方法得到相应对象的拷贝对象. 比如哆啦A梦的复制镜,一照,就把物品拷贝了一份(虽然是镜子复制是相反的,这里就忽略这个细节了) C++中依靠拷贝构 ...
- 《JAVA设计模式》之原型模式(Prototype)
在阎宏博士的<JAVA与模式>一书中开头是这样描述原型(Prototype)模式的: 原型模式属于对象的创建模式.通过给出一个原型对象来指明所有创建的对象的类型,然后用复制这个原型对象的办 ...
- 设计模式入门之原型模式Prototype
//原型模式:用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象 //简单来说,当进行面向接口编程时,假设须要复制这一接口对象时.因为不知道他的详细类型并且不能实例化一个接口 //这时就须要 ...
- [工作中的设计模式]原型模式prototype
一.模式解析 提起prototype,最近看多了js相关的内容,第一印象首先是js的原型 var Person=function(name){ this.name=name; } Person.pro ...
随机推荐
- [BZOJ2821]作诗
description 在线询问区间内出现次数为正偶数的数的种数. data range \[n,m\le 10^5\] solution 分块大法好 首先离散化权值 这种对于权值做询问并且询问放在一 ...
- bzoj2724: [Violet 6]蒲公英(离散化+分块)
我好弱啊..这题调了2天QwQ 题目大意:给定一个长度为n(n<=40000)的序列,m(m<=50000)次询问l~r之间出现次数最多的数.(区间众数) 这题如果用主席树就可以不用处理一 ...
- Android Json解析与总结
一.JSON定义 JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式. 易于人阅读和编写.同时也易于机器解析和生成. 它基于JavaScript Progra ...
- 背景建模技术(六):帧处理(FrameProcessor)模块
前面几篇文章简单介绍了BgsLibrary的入口函数.视频分析和视频捕获模块,本文将简单介绍帧处理模块,即对每一帧进行处理的函数,也就是真正调用背景建模算法的接口处. 下面贴出源码供大家分析: #in ...
- [10.12模拟赛] 老大 (二分/树的直径/树形dp)
[10.12模拟赛] 老大 题目描述 因为 OB 今年拿下 4 块金牌,学校赞助扩建劳模办公室为劳模办公室群,为了体现 OI 的特色,办公室群被设计成了树形(n 个点 n − 1 条边的无向连通图), ...
- acm1217教训
能用容器去做的用容器做,尽量少用数组,即使自己明确其数量的上届: #include<iostream> #include<cstring> #include<map> ...
- 一图看懂深度学习框架对比----Caffe Torch Theano TensorFlow
Caffe Torch Theano TensorFlow Language C++, Python Lua Python Python Pretrained Yes ++ Yes ++ Yes ...
- [USACO06NOV] Roadblocks
https://www.luogu.org/problem/show?pid=2865 题目描述 Bessie has moved to a small farm and sometimes enjo ...
- PHP日期时间操作
一.设置时区 date_default_timezone_set('PRC'); 二.获取当前时间的 Unix 时间戳(格林威治时间 1970 年 1 月 1 日 00:00:00到当前时间的秒数)和 ...
- 【51NOD-0】1137 矩阵乘法
[算法]简单数学 [题解] 对于A*B=C C中第i行第j列的数字由A中第i行和B中的j列的数字各自相乘后相加得到. 所以两个矩阵能相乘要求A的列数等于B的行数,复杂度为O(n3). #include ...