原型模式:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。(要创建一个对象,这个对象为实现原型接口,方法是原型克隆。克隆只是方法而不是原型模式的目的,创建对象才是目的)

UML类图:

构成:

1.原型接口,提供给客户操作,声明一个clone()方法,用于克隆自身创建另一个实例

2.原型,实现clone()方法,分为浅层克隆和深层克隆。浅层克隆,值类型成员的值相同,但是在内存是存储在不同空间上的,而引用类型成员是相同的引用,即是同一块内存空间,修改其中一个,另一个也随之改变。而深层克隆,不论是值类型还是引用类型,都是不同的内存。

以电脑为例,先定义电脑接口,包含clone()方法

 interface Computer
{
string CPU { get; set; }
string Memory { get; set; }
//string GPU { get; set; }
GPU GPU { get; set; }
Computer clone();
Computer deepClone();
}

原型实现这个接口,因为.NET所有类都是object的子类,而object类有一个MemberwiseClone()方法返回自身的浅层克隆,所以可以用它实现浅层克隆clone()(自己实现?)。而深层克隆deepClone()是用序列化和反序列化实现的(这个现在还不懂为什么)

class ComputerPrototype : Computer
{
private string cpu;
private string memory;
private GPU gpu;
public Computer clone()
{
return (Computer)this.MemberwiseClone();
}
public Computer deepClone()
{
MemoryStream stream = new MemoryStream();
BinaryFormatter formatter = new BinaryFormatter();
formatter.Serialize(stream, this);
stream.Position = ;
return formatter.Deserialize(stream) as Computer;
}
public override string ToString()
{
return CPU + "\n" + Memory + "\n" + GPU.Producer+" "+gpu.Type;
}
public GPU GPU
{
get { return gpu; }
set { gpu = value; }
}
public string Memory
{
get { return memory; }
set { memory = value; }
}
public string CPU
{
get { return cpu; }
set { cpu = value; }
}
}

Computer包含一个类GPU,用来演示浅层和深层克隆的不同,它被标记为可序列化

[Serializable]
class GPU
{
public GPU(string producer, string type)
{
this.Producer = producer;
this.Type = type;
}
public string Producer
{
get;
set;
}
public string Type
{
get;
set;
}
}

先实例化一个ComputerPrototype原型,再为它的成员赋值,接下来,通过浅层克隆方法clone()创建一个实例,修改新实例的成员,最后查看两个实例的异同

class Program
{
static void Main(string[] args)
{
Computer low = new ComputerPrototype();
low.CPU = "e3 1231v3";
low.Memory = "4 G";
low.GPU = new GPU("凄惨红", "GTX970");
//Computer high = low.deepClone();
Computer high = low.clone(); high.GPU.Producer = "高贵的阿苏斯";
high.Memory = "8 G";
Console.Write("GPU是否是同一引用:");
Console.WriteLine(low.GPU == high.GPU); Console.WriteLine("Low:");
Console.WriteLine(low.ToString());
Console.WriteLine("High:");
Console.WriteLine(high.ToString());
Console.ReadKey();
}
}

结果如下

结果表明,两个实例的GPU是同一引用,修改了克隆,原型也被修改了,但是Memory确是各自独立的,修改克隆并不影响原型。

而将clone()改为执行deepClone()方法结果为

这表明,两个实例GPU为不同引用,修克隆的GPU和Memory不会影响原型。

效果:

1.运行时刻增加和删除产品。运行时注册原型就可以增加新的产品(low是一个新产品)

2.改变值以指定新对象。减少需要的类的数量(通过改变一些值,创建无数种对象,high为一个新对象)

3.改变结构以指定新对象。(?)

4.减少子类的构造。工厂方法,一个产品一个ConcreteCreator,而原型模式不需要

5.用类动态配置应用。

设计模式C#实现(八)——原型模式的更多相关文章

  1. 设计模式(六)原型模式(Prototype Pattern)

    一.引言 在软件系统中,当创建一个类的实例的过程很昂贵或很复杂,并且我们需要创建多个这样类的实例时,如果我们用new操作符去创建这样的类实例,这未免会增加创建类的复杂度和耗费更多的内存空间,因为这样在 ...

  2. 设计模式学习系列6 原型模式(prototype)

    原型模式(prototype)用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象.允许一个对象再创建另外一个新对象的时候根本无需知道任何创建细节,只需要请求圆形对象的copy函数皆可. 1 ...

  3. 设计模式(四)原型模式Prototype(创建型)

      设计模式(四)原型模式Prototype(创建型) 1.   概述 我们都知道,创建型模式一般是用来创建一个新的对象,然后我们使用这个对象完成一些对象的操作,我们通过原型模式可以快速的创建一个对象 ...

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

    Prototype模式定义:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象. Prototype模式允许一个对象再创建另外一个可定制的对象,根本无需知道任何如何创建的细节,工作原理是: ...

  5. 设计模式 --> (6)原型模式

    原型(Prototype)模式 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象. 原型模式是一种创建型设计模式,Prototype模式允许一个对象再创建另外一个可定制的对象,根本无需知 ...

  6. 设计模式(5)原型模式(Prototype)

    设计模式(0)简单工厂模式 设计模式(1)单例模式(Singleton) 设计模式(2)工厂方法模式(Factory Method) 设计模式(3)抽象工厂模式(Abstract Factory) 设 ...

  7. 面向对象设计模式纵横谈:Prototype 原型模式(笔记记录)

       有一段时间没写东西了,今天继续把没写完的设计模式写完,今天这堂课是创建型设计模式的最后一堂课,原型设计模式,它同样也是解决了对象在创建的过程中的解耦合的情况,面对变化使代码更稳定,更准确的说是使 ...

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

    Prototype 原型模式(创建型模式) 依赖关系的倒置抽象不应该依赖于实现细节,细节应该依赖于抽象.对所有的设计模式都是这样的. -抽象A直接依赖于实现细节b -抽象A依赖于抽象B,实现细节b依赖 ...

  9. 大型Java进阶专题(五) 设计模式之单例模式与原型模式

    前言 ​ 今天开始我们专题的第四课了,最近公司项目忙,没时间写,今天抽空继续.上篇文章对工厂模式进行了详细的讲解,想必大家对设计模式合理运用的好处深有感触.本章节将介绍:单例模式与原型模式.本章节参考 ...

  10. 【设计模式】Java设计模式精讲之原型模式

    简单记录 - 慕课网 Java设计模式精讲 Debug方式+内存分析 & 设计模式之禅-秦小波 文章目录 1.原型模式的定义 原型-定义 原型-类型 2.原型模式的实现 原型模式的通用类图 原 ...

随机推荐

  1. Sql Server来龙去脉系列 必须知道的权限控制核心篇

    最近写了<Sql Server来龙去脉系列  必须知道的权限控制基础篇>,感觉反响比较大.这可能也说明了很多程序猿对数据库权限控制方面比较感兴趣,或者某些技术点了解的没有很透彻. 有些人看 ...

  2. 局域网电脑Sql2008 R2无法连接到localhost 解决方案

    1.自己电脑加入加入了公司域的话,链接Sql Server服务器,用127.0.0.1或.或localhost登录时会提示如下错误: 2.解决措施: 打开Sql配置管理器->SqlServer网 ...

  3. 重新想象 Windows 8.1 Store Apps (85) - 警报通知(闹钟), Tile 的新特性

    [源码下载] 重新想象 Windows 8.1 Store Apps (85) - 警报通知(闹钟), Tile 的新特性 作者:webabcd 介绍重新想象 Windows 8.1 Store Ap ...

  4. 创建WCF服务自我寄宿

    WCF服务的寄宿方式 WCF寄宿方式是一种非常灵活的操作,可以寄宿在各种进程之中,常见的寄宿有: IIS服务.Windows服务.Winform程序.控制台程序中进行寄宿,从而实现WCF服务的运行,为 ...

  5. yii2.0 图片上传(摘录)

    文章来源:http://blog.sina.com.cn/s/blog_88a65c1b0101izmn.html 下面小伙就带领大学学习一下 Yii2.0 的图片上传类的使用,还是老样子,如果代码样 ...

  6. C语言回滚(二)--循环打印

    //1.用循环打印 /* FFEFEDFEDCFEDCBFEDCBA */ #include <stdio.h> #include<stdlib.h> int main(){ ...

  7. 如何使用mybatis《一》

    mybatis作为ORM轻量级框架一出现就吸引了无数人的眼球,比hibernate要简单且入门较容易,下面开始我的第一个mybatis程序. 一.下载mybatis的包 我们知道任何一个框架都会有其包 ...

  8. 【FFmpeg】ffplay播放rtsp视频流花屏问题

    问题描述:ffplay播放rtsp视频流时,播放过程中随机出现花屏现象. 基本流程学习:阅读ffplay源码,熟悉其播放rtsp视频流的基本流程. 在ffplay源码阅读和分析的基础上,画出了其播放r ...

  9. springmvc+mybatis+spring 整合

    获取[下载地址]   [免费支持更新]三大数据库 mysql  oracle  sqlsever   更专业.更强悍.适合不同用户群体[新录针对本系统的视频教程,手把手教开发一个模块,快速掌握本系统] ...

  10. .net aes加密视频等文件

    公司学习平台在app端下载下来的视频需要加密 随查找资料参考一些写法 写了aes的加密方法 记录防止忘记 using System; using System.Collections.Generic; ...