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

依赖关系的倒置
抽象不应该依赖于实现细节,细节应该依赖于抽象。对所有的设计模式都是这样的。

-抽象A直接依赖于实现细节b

-抽象A依赖于抽象B,实现细节b依赖于抽象B

动机(Motivation)

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

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

意图(Intent)

使用原型实例指定创建对象的种类,然后通过拷贝这些原型来创建新的对象。——《设计模式》GoF

示例代码:

    /// <summary>
/// 普通兵
/// </summary>
public abstract class NormalActor
{
public abstract NormalActor Clone();
}
/// <summary>
/// 飞行兵
/// </summary>
public abstract class FlyActor
{
public abstract FlyActor Clone();
}
/// <summary>
/// 水兵
/// </summary>
public abstract class WaterActor
{
public abstract WaterActor Clone();
}
    public class NormalActorA : NormalActor
{
public override NormalActor Clone()
{
//或者强转成NormalActorA也行
//return (NormalActorA)this.MemberwiseClone();
return (NormalActor)this.MemberwiseClone();//浅拷贝,对于值类型+string类型是OK的,但是如果有其他的引用类型就不行了(clone的只是地址)
//通过序列化来解决浅拷贝的问题
}
}
public class FlyActorA : FlyActor
{
public override FlyActor Clone()
{
throw new NotImplementedException();
}
}
public class WaterActorA : WaterActor
{
public override WaterActor Clone()
{
throw new NotImplementedException();
}
}
    public class GameSystem
{
public void Run()
{
NormalActorA normalActor1 = new NormalActorA();//GameSystem(抽象)依赖于NormalActorA(具体)了
NormalActorA normalActor2 = new NormalActorA();
NormalActorA normalActor3 = new NormalActorA();
NormalActorA normalActor4 = new NormalActorA(); FlyActorA flyActor1 = new FlyActorA();
FlyActorA flyActor2 = new FlyActorA(); WaterActorA waterActor1 = new WaterActorA();
WaterActorA waterActor2 = new WaterActorA();
}
//======由于上面的Run导致抽象依赖于具体了,所以要改为下面的依赖于抽象=======>
public void Run(NormalActor normalActor, FlyActor flyActor, WaterActor waterActor)
{ //NormalActor为NormalActorA的抽象
NormalActor normalActor1 = normalActor.Clone();
NormalActor normalActor2 = normalActor.Clone();
NormalActor normalActor3 = normalActor.Clone();
NormalActor normalActor4 = normalActor.Clone(); FlyActor flyActor1 = flyActor.Clone();
FlyActor flyActor2 = flyActor.Clone(); WaterActor waterActor1 = waterActor.Clone();
WaterActor waterActor2 = waterActor.Clone();
}
}

Prototype模式的几个要点

Prototype模式同样用于隔离类对象的使用者和具体类型(易变类)之间的耦合关系,它同样要求这些“易变类”拥有“稳定的接口”。

Prototype模式对于“如何创建易变类的实体对象”采用“原型克隆”的方法来做,它使我们非常灵活地创建“拥有某些稳定接口”的新对象——所需的工作仅仅是注册一个新类的对象(即原型),然后在任何需要的地方不断地Clone。

Prototype模式中的Clone方法可用利用.NET中的Object类的MemberwiseClone()方法或者序列化(可以实现深拷贝)来实现。

有关创建型模式的讨论

Singleton模式解决的是实体对象个数的问题。除了Singleton之外,其他创建型模式解决的都是new所带来的耦合关系。

Factory Method,Abstract Factory,Builder都需要一个额外的工厂类来负责实例化“易变对象”,而Prototype则是通过原型(一个特殊的工厂类)来克隆“易变对象”。

如果遇到“易变类”,起初的设计通常从Factory Method开始,当遇到更多复杂变化时,在考虑重构为其他三种工厂模式(Abstract Factory,Builder,Prototype)。

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

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

    依赖关系的倒置:抽象不应该依赖于实现的细节,实现细节应该依赖于抽象. 原型模式的定义 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象.prototype模式允许一个对象再创建另外一个可 ...

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

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

  3. php设计模式(一):简介及创建型模式

    我们分三篇文章来总结一下设计模式在PHP中的应用,这是第一篇创建型模式. 一.设计模式简介 首先我们来认识一下什么是设计模式: 设计模式是一套被反复使用.容易被他人理解的.可靠的代码设计经验的总结. ...

  4. FactoryMethod工厂方法模式(创建型模式)

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

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

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

  6. .NET设计模式(7):创建型模式专题总结(Creational Pattern)(转)

    概述 创建型模式,就是用来创建对象的模式,抽象了实例化的过程.它帮助一个系统独立于如何创建.组合和表示它的那些对象.本文对五种常用创建型模式进行了比较,通过一个游戏开发场景的例子来说该如何使用创建型模 ...

  7. .NET设计模式(7):创建型模式专题总结(Creational Pattern)

    ):创建型模式专题总结(Creational Pattern)    创建型模式专题总结(Creational Pattern) --.NET设计模式系列之七 Terrylee,2006年1月 转载: ...

  8. C#面向对象设计模式纵横谈——2.Singleton 单件(创建型模式)

    一:模式分类 从目的来看: 创建型(Creational)模式:负责对象创建. 结构型(Structural)模式:处理类与对象间的组合. 行为型(Behavioral)模式:类与对象交互中的职责分配 ...

  9. 设计模式(二): BUILDER生成器模式 -- 创建型模式

    1.定义 将一个复杂对象的构造与它的表示分离,使同样的构建过程可以创建不同的表示,这样的设计模式被称为建造者模式. 2.适用场景 1. 当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式 ...

  10. 设计模式(Java版)-创建型模式之简单工厂模式

    前言:这段时间在学习设计模式,本人也是小菜一枚(所以写的如果有错误的地方请大大们给予指出).这个东西也是我一直想学习的,从点点滴滴做起,记录下自己每天的领悟! 一.工厂模式的动机 在软件系统中,经常面 ...

随机推荐

  1. 常用map总结

    Map map = new HashMap(); Iterator it = map.entrySet().iterator(); while (it.hasNext()) { Map.Entry e ...

  2. Qt WebRTC demo

    This is a very simple demonstration of how to stream from a native application to the browser using ...

  3. Mybatis拦截器介绍及分页插件

    1.1    目录 1.1 目录 1.2 前言 1.3 Interceptor接口 1.4 注册拦截器 1.5 Mybatis可拦截的方法 1.6 利用拦截器进行分页 1.2     前言 拦截器的一 ...

  4. 查询mysql 哪些表正在被锁状态

    查询mysql 哪些表正在被锁状态 show OPEN TABLES where In_use > 0; 参考链接:http://zhidao.baidu.com/link?url=tCQ70t ...

  5. Rest之路 - 第一个Rest程序

    在 Eclipse 里新建一个 Dynamic project 将 Jersey 的 jar 包,拷贝到 WebContent -> WEB-INF -> lib 文件夹 Add jars ...

  6. 小程序二维码生成接口API

    获取小程序码 我们推荐生成并使用小程序码,它具有更好的辨识度.目前有两个接口可以生成小程序码,开发者可以根据自己的需要选择合适的接口. 接口A: 适用于需要的码数量较少的业务场景 接口地址: http ...

  7. flask系列一之环境搭建包安装

    一,python的安装 (1)python的安装 (2)虚拟环境的配置 参考:http://www.cnblogs.com/bfwbfw/p/7995245.html 1,虚拟环境的建立 (1)使用p ...

  8. Sublime Text 套件介紹:Pretty JSON

    JSON,一個輕量級的資料交換語言,目前許多網站AJAX request的回應結果都是JSON格式   以下是一個標準的JSON格式   1 2 3 4 5 6 7 8 9 10 11 12 13 1 ...

  9. asp:GridView控件的使用

    使用asp:GridView显示一个统计的表格 cs样式: <style>        table.gridview_m        {            border-colla ...

  10. Super Jumping! Jumping! Jumping(最大递增子序列的和)

    Nowadays, a kind of chess game called “Super Jumping! Jumping! Jumping!” is very popular in HDU. May ...