依赖关系的倒置:抽象不应该依赖于实现的细节,实现细节应该依赖于抽象。

原型模式的定义

用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。prototype模式允许一个对象再创建另外一个可定制对的对象,根本无需知道任何创建的细节,工作原理是:通过将一个原型对象传给那个要发动创建的对象,这个要发动创建的对象通过请求原型对象拷贝他们自己来实施创建。

动机(Motivation)

在软件系统中,经常面临着“某些结构复杂的对象”的创建工作;由于需求的变化,这些对象经常面临着剧烈的变化,但他们却拥有比较稳定一致的接口。

如何应对这种变化?如何向“客户程序(使用这些对象的程序)”隔离出“这些易变的对象”,从而使得依赖这些易变对象的客户程序不随着需求改变而改变?

场景

我们在做一个游戏程序(GameSystem),现在我们需要五个普通的小兵,两个会飞的小兵和两个能在水里游的小兵,我们刚开始可能会这样实现

namespace Prototype
{
public class GameSystem
{
public void Run()
{
NormalActor normalActor1 = new NormalActor();
NormalActor normalActor2 = new NormalActor();
NormalActor normalActor3 = new NormalActor(); NormalActor normalActor4 = new NormalActor(); NormalActor normalActor5 = new NormalActor(); FlyActor flyActor1 = new FlyActor(); FlyActor flyActor2 = new FlyActor(); WaterActor waterActor1 = new WaterActor(); WaterActor waterActor2 = new WaterActor();
}
} public class NormalActor
{
} public class FlyActor
{
} public class WaterActor
{
}
}

但是这种实现违背了我们刚开始讲的依赖关系倒置的思想,GameSystem这个抽象依赖了实现细节,具体的NormalActor和

FlyActor以及WaterActor,这个时候如果这些具体点额实现细节改变的话,对我们的开发会造成很大的麻烦。这个时候怎么办呢?我们完全可以用设计模式来实现这个功能而避免因改变而造成的困境,比如工厂方法,抽象工厂,我们也可以用原型模式来实现。我们来看原型模式的实现代码

namespace Prototype
{
public class GameSystem
{
public void Run(NormalActor normalActor, FlyActor flyActor, WaterActor waterActor)
{
NormalActor normalActor1 = normalActor.Clone();
NormalActor normalActor2 = normalActor.Clone();
NormalActor normalActor3 = normalActor.Clone(); NormalActor normalActor4 = normalActor.Clone(); NormalActor normalActor5 = normalActor.Clone(); FlyActor flyActor1 = flyActor.Clone(); FlyActor flyActor2 = flyActor.Clone(); WaterActor waterActor1 = waterActor.Clone(); WaterActor waterActor2 = waterActor.Clone();
}
}
#region 抽象类 public abstract class NormalActor
{
public abstract NormalActor Clone();
} public abstract class FlyActor
{
public abstract FlyActor Clone();
} public abstract class WaterActor
{
public abstract WaterActor Clone();
}
#endregion #region 具体的实现类
public class NormalActorA : NormalActor
{
public override NormalActor Clone()
{
return (NormalActor)this.MemberwiseClone();
}
} public class NormalActorB : NormalActor
{
public override NormalActor Clone()
{
return (NormalActor)this.MemberwiseClone();
}
} public class FlyActorA : FlyActor
{
public override FlyActor Clone()
{
return (FlyActor)this.MemberwiseClone();
}
} public class FlyActorB : FlyActor
{
public override FlyActor Clone()
{
return (FlyActor)this.MemberwiseClone();
}
}
//WaterActorA
public class WaterActorA : WaterActor
{
public override WaterActor Clone()
{
return (WaterActor)this.MemberwiseClone();
}
}
//WaterActorB
public class WaterActorB : WaterActor
{
public override WaterActor Clone()
{
return (WaterActor)this.MemberwiseClone();
}
}
#endregion
}

利用了.NET框架的Clone,但是这个MemberwiseClone是一个浅拷贝,所以如果类里面有引用类型的实例话会拷贝出同一个对象。我们可以用序列化和反序列化的方式得到一个我们想要得到的对象。这就是原型模式的实现方式,

Prototype原型(创建型模式)的更多相关文章

  1. 设计模式学习之原型模式(Prototype,创建型模式)(5)

    通过序列化的方式实现深拷贝 [Serializable] public class Person:ICloneable { public string Name { get; set; } publi ...

  2. 设计模式(五):PROTOTYPE原型模式 -- 创建型模式

    1.定义 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象. 2.适用场景 原型模式的主要思想是基于现有的对象克隆一个新的对象出来,一般是有对象的内部提供克隆的方法,通过该方法返回一个对 ...

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

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

  4. Prototype原型模式(创建型模式)

    1.原型模式解决的问题 现在有一个抽象的游戏设施建造系统,负责构建一个现代风格和古典风格的房屋和道路. 前提:抽象变化较慢,实现变化较快(不稳定) 整个抽象的游戏设施建造系统相对变化较慢,本例中只有一 ...

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

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

  6. 跟着实例学习设计模式(7)-原型模式prototype(创建型)

    原型模式是创建型模式. 设计意图:用原型实例指定创建对象的类型,并通过拷贝这个原型来创建新的对象. 我们使用构建简历的样例的类图来说明原型模式. 类图: 原型模式主要用于对象的复制.它的核心是就是类图 ...

  7. 创建型模式(五) 原型模式(Prototype)

    一.动机(Motivation) 在软件系统中,经常面临着"某些结构复杂的对象"的创建工作:由于需求的变化,这些对象经常面临着剧烈的变化,但是它们却拥有比较稳定一致的接口.如何应对 ...

  8. 设计模式(4)-对象创建型模式-Prototype模式

    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) - ...

  9. Prototype,创建型模式

    读书笔记_探索式测试_混合探索式测试   一.测试场景 1.讲述用户故事 2.描述需求 3.演示产品功能 4.演示集成场景 5.描述设置和安装 6.描述警告和出错情况 二.使用基于场景的探索式测试 1 ...

  10. 设计模式之美:Creational Patterns(创建型模式)

    创建型模式(Creational Patterns)抽象了对象实例化过程. 它们帮助一个系统独立于如何创建.组合和表示它的那些对象. 一个类创建型模式使用继承改变被实例化的类. 一个对象创建型模式将实 ...

随机推荐

  1. 关于XAMPP默认端口80 和443被占用的问题

    关于安装xampp-win32-1.8.1-VC9-installer.zip后启动时候报端口80和443被占用的问题解决 xampp-win32-1.8.1-VC9-installer.zip下载地 ...

  2. 【grunt第一弹】30分钟学会使用grunt打包前端代码

    前言 以现在前端js激增的态势,一个项目下来几十个js文件轻轻松松对于复杂一点的单页应用来说,文件上百简直是家常便饭,那么这个时候我们的js文件应该怎么处理呢?另外,对于css文件,又该如何处理呢?? ...

  3. 『SharePoint』Content Editor Webpart不能添加引用_layouts下面的文件

    好久没写了,最近没怎么学到新东西,倒是犯了一个很常见的错误,那就是试图在content editor webpart中添加位于_layouts下面的一个txt文件,虽然这个txt中只是几行简单的htm ...

  4. iOS之设置头像(访问系统相册、本地上传)

    1. UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:                               ...

  5. Git常用命令总结

    Git常用命令总结 git init      在本地新建一个repo,进入一个项目目录,执行git init,会初始化一个repo,并在当前文件夹下创建一个.git文件夹.   git clone ...

  6. [转]看懂UML类图

    这里不会将UML的各种元素都提到,我只想讲讲类图中各个类之间的关系: 能看懂类图中各个类之间的线条.箭头代表什么意思后,也就足够应对 日常的工作和交流: 同时,我们应该能将类图所表达的含义和最终的代码 ...

  7. Oracle 释放flash recovery area的四种方法

    早上收到一台Linux服务器磁盘告警邮件以及监控告警日志程序发来的邮件.检查过后,发现Linux服务器中一个分区没有空间了.主要原因是由于昨晚程序员做升级时,产生了大量的归档日志,导致联机重做日志无法 ...

  8. Linux命令学习总结: file命令

    命令简介: 该命令用来识别文件类型,也可用来辨别一些文件的编码格式.它是通过查看文件的头部信息来获取文件类型,而不是像Windows通过扩展名来确定文件类型的. 执行权限 :All User 指令所在 ...

  9. SQL Server里面如何检查没有释放的游标

    一直以来对SQL SERVER的游标都不怎么感冒,也很少使用SQL Server里面的游标,前几天有一位网友问如何检查数据库里面没有释放的游标,觉得有点意思,就测试验证了一下,顺便整理于此. 会话1: ...

  10. mac xcode c++ cin cout注意细节一

    #include <iostream> using namespace std; 要同时存在 要不然std命名空间无法生效