//---------------------------15/04/07----------------------------

//prototype 原型模式--对象创建型模式

/*

1:意图:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。

2:动机:

3:适用性:

1>当一个系统应该独立于它的产品创建、构成和表示时

2>当要实例化的类是在运行时刻制定时,例如通过动态装载

3>为了避免创建一个与产品类层次平行的工厂类层次时

4>当一个类的实例只能有几个不同状态组合中的一种时

4:结构:

Client:

prototype------------------------------->Prototype:

Operation()                              Clone()

{ p = prototype->Clone()}                   |

|                   |

ConcretePrototype1:     ConcretePrototype2:

Clone()                 Clone()

{return copy of self}   {return copy of self}

5:参与者:

1>Prototype:声明一个克隆自身的接口。

2>ConcretePrototype:实现一个克隆自身的操作。

3>Client:让一个原型克隆自身从而创建一个新的对象。

6:协作:客户请求一个原型克隆自身。

7:效果:

1>优点:

1)运行时刻可以增加和删除产品,更加灵活。

2)改变值以指定新对象。
可以为对象指定新值来实例化新的对象,

这种设计可以极大减少系统所需的类的数目。

3)改变结构以制定新对象。
针对一些由部件和子部件来创建的对象,

反映了Composite模式(改变child的多少或类型等)以及Decorator模式(暂时不知道<未知标记>)

这里Clone需要实现为深拷贝,不然child都是一样的这个结构改变一下,别的结构就跟着改变了。

4)减少子类的构造。相比较于Factory Method,不需要创建一个creator类层次,

需要一个对象时只用克隆一个就行,而不是靠creator类创建。

5)用类动态配置应用(不懂<未知标记>)

2>缺陷:

每一个子类都必须实现Clone操作。当类已经存在,新增Clone操作会很难。当内部包括一些不

支持拷贝(不支持拷贝,就无法调用拷贝构造函数实现Clone操作)或有循环引用(要实现深拷贝,就

要不断重复了)的对象时,实现克隆也会很困难。

8:实现:

1>使用一个原型管理器。
当一个系统中原型数目不固定时(也就是,客户会动态创建和销毁),要保持一个可

用原型的注册表。客户可以通过注册表来存储和检索原型。

2>实现克隆操作。对一些复杂的对象进行深拷贝。

3>初始化克隆对象
如果原型的类已经定义好了设置关键状态的操作就不用提供initialize操作,

否则,就必须提供一个initialize操作来初始化参数。

9:代码示例:                                                         */

//原型工厂

class MazePrototypeFactory :
public MazeFactory

{

public:

MazePrototypeFactory(Maze*, Wall*, Room*, Door*);

virtual Maze* MakeMaze()
const;

virtual Room* MakeRoom(int)
const;

virtual Wall* MakeWall()
const;

virtual Door* MakeDoor(Room*, Room*)
const;

private:

Maze*   _prototypeMaze;

Room*   _prototypeRoom;

Wall*   _prototypeWall;

Door*   _prototypeDoor;

};

//初始化每一个原型

MazePrototypeFactory::MazePrototypeFactory

(Maze* m, Wall* w, Room* r, Door* d)

{

_prototypeMaze = m;

_prototypeRoom = r;

_prototypeWall = w;

_prototypeDoor = d;

}

//实现基类的virtual方法,内部调用Clone实现

Wall* MazePrototypeFactory::MakeWall()
const

{

return _prototypeWall->Clone();

}

//效用Clone后还要初始化克隆对象

Door* MazePrototypeFactory::MakeDoor(Room* r1, Room* r2)
const

{

Door* door = _prototypeDoor->Clone();

door->Initialize(r1, r2);

return door;

}

//使用方法

MakeGame game;

MazePrototypeFactory simpleMazeFactor(new Maze,
new Wall, new Room,
new Door);

maze* maze = game.CreateMaze(simpleMazeFactor);

/////////

//下面要换其中的部件,来实现新的“原型类”,要作为部件,必须实现clone操作

MazePrototypeFactory bombedMazeFactory(

new Maze,
new BombedWall, new RoomWithABomb,
new Door);

//Door中有两个数据可以设置或者说需要设置,所以要提供一个initilize函数

class Door :
public MapSite

{

public:

Door();

Door(const Door&);

virtual void Initialize(Room*, Room*);

virtual Door* Clone()
const;

virtual void Enter();

Room* OtherSideFrom(Room*);

private:

Room* _room1;

Room* _room2;

};

Door::Door (const Door& other)

{

_room1 = other._room1;

_room2 = other._room2;

}

void Door::Initialize(Room* r1, Room* r2)

{

_room1 = r1;

_room2 = r2;

}

Door* Door::Clone()
const

{

return new Door(*this);

}

//这里应该也有一个initialize函数才对。用来设置是否有炸弹

class BombedWall :
public wall

{

public:

BombedWall();

BombedWall(const BombedWall&);

virtual Wall* Clone()
const;

bool HasBomb();

private:

bool _bomb;

};

BombedWall::BombedWall(const BombedWall& other) : Wall(other)

{

_bomb = other._bomb;

}

Wall* BombedWall::Clone()
const

{

return new BombedWall(*this);

}

//这样子每次用的时候都要重新使用部件创建一个“类”。

//可以用一个map把“类”存起来

map<string,MazePrototypeFactory> MazeTable;

MazeTable.insert(make_pair("bombedMazeFactory",bombedMazeFactory));

//要用的时候取出:

game.CreateMaze(map["bombedMazeFactory"]);

//可以把直接map封装到game中,然后致用传入一个字符串就行。

//不过这样需要提供一个注册函数和销毁函数,来对“类”进行注册和销毁。

//下面是ios设计模式解析版本的:

/*

1:在以下情形,会考虑使用原型模式:

1>需要创建的对象应独立于其类型与创建方式。(太抽象<未知标记>)

2>要实例化的类是在运行时决定的。

3>不想要与产品层次相对应的工厂层次。

4>不同类的实例间的差异仅仅是状态的若干组合。因此复制响应数量的原型比手工实例化更加方便。

5>类不容易创建,比如每个组件可以把其他组件作为子节点的组合对象。复制已有的组合

对象,并对副本进行修改会更加容易。

2:考虑使用原型模式的情景:

1>有很多相关的类,其行为略不同,而且主要差别在于内部属性,比如名称,图像等;

2>徐傲使用组合对象作为其他东西的基础,比如,使用组合对象作为组件来构建另一个组合对象。

*/

设计模式 笔记 原型模式 prototype的更多相关文章

  1. 乐在其中设计模式(C#) - 原型模式(Prototype Pattern)

    原文:乐在其中设计模式(C#) - 原型模式(Prototype Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 原型模式(Prototype Pattern) 作者:weba ...

  2. 二十四种设计模式:原型模式(Prototype Pattern)

    原型模式(Prototype Pattern) 介绍用原型实例指定创建对象的种类,并且通过拷贝这个原型来创建新的对象.示例有一个Message实体类,现在要克隆它. MessageModel usin ...

  3. [设计模式] 4 原型模式 prototype

    设计模式:可复用面向对象软件的基础>(DP)本文介绍原型模式和模板方法模式的实现.首先介绍原型模式,然后引出模板方法模式. DP书上的定义为:用原型实例指定创建对象的种类,并且通过拷贝这些原型创 ...

  4. python 设计模式之原型模式 Prototype Pattern

    #引入 例子1: 孙悟空拔下一嘬猴毛,轻轻一吹就会变出好多的孙悟空来. 例子2:寄个快递下面是一个邮寄快递的场景:“给我寄个快递.”顾客说.“寄往什么地方?寄给……?”你问.“和上次差不多一样,只是邮 ...

  5. 【UE4 设计模式】原型模式 Prototype Pattern

    概述 描述 使用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象.如孙悟空猴毛分身.鸣人影之分身.剑光分化.无限剑制 原型模式是一种创建型设计模式,允许一个对象再创建另外一个可定制的对象, ...

  6. 学习笔记——原型模式Prototype

    原型模式,简单说就是具有一个克隆方法,外部可以直接使用此方法得到相应对象的拷贝对象. 比如哆啦A梦的复制镜,一照,就把物品拷贝了一份(虽然是镜子复制是相反的,这里就忽略这个细节了) C++中依靠拷贝构 ...

  7. 【设计模式】—— 原型模式Prototype

    前言:[模式总览]——————————by xingoo 模式意图 由于有些时候,需要在运行时指定对象时哪个类的实例,此时用工厂模式就有些力不从心了.通过原型模式就可以通过拷贝函数clone一个原有的 ...

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

    结构   意图 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象. 适用性 当要实例化的类是在运行时刻指定时,例如,通过动态装载:或者 为了避免创建一个与产品类层次平行的工厂类层次时:或 ...

  9. 设计模式五: 原型模式(Prototype)

    简介 原型模式是属于创建型模式的一种,是通过拷贝原型对象来创建新的对象. 万能的Java超类Object提供了clone()方法来实现对象的拷贝. 可以在以下场景中使用原型模式: 构造函数创建对象成本 ...

随机推荐

  1. FTP上传下载类

    public class FtpOperation { public static void UploadFile(FileInfo fileinfo, string targetDir, strin ...

  2. 跨过Django的坑

    在最近的Django的学习中,慢慢的开始踩坑,开此栏,专为收纳Django的坑,在以后的学习中以便警示.(使用工具为pycharm专业版2018.2.4,python3.5.2,Django版本2.1 ...

  3. springMvc之文件上传与下载

    我们经常会使用的一个功能是文件下载,既然有文件下载就会有文件上传,下面我们来看一下文件上传是如何实现的 首先准备好一个页面 <style type="text/css"> ...

  4. android的hwc浅析【转】

    https://blog.csdn.net/alien75/article/details/39290109 注:本文档基于kk进行分析,着重于概念的精确定义和版本历史演变 一.关于hwc的介绍 广义 ...

  5. python Anaconda

    转载自   https://blog.csdn.net/program_developer/article/details/79677557 目录: Anaconda是什么? 如何安装? 如何管理包? ...

  6. [Python_3] Python 函数 & IO

    0. 说明 Python 函数 & IO 笔记,基于 Python 3.6.2 参考  Python: read(), readline()和readlines()使用方法及性能比较  Pyt ...

  7. NOIP2018考前抱佛脚——数据结构基础及STL实现

    目录 动态数组 栈 队列 优先队列 动态数组 srand(time(0)); std::vector<int> qwq; for(int i = 1;i <= 10;++i) qwq ...

  8. 阿里八八Alpha阶段Scrum(10/12)

    今日进度 叶文滔: 正在解决日程模块合并至主项目的问题 俞鋆: 完成了上传和下载头像的api,完善了登陆和注册的api 李嘉群: 正在尝试json文件的转化和发送请求 黄梅玲: 学习json数据解析和 ...

  9. Post-installation steps for Chromium | Fedora

    Flash 插件安装 网址: https://fedora.pkgs.org/ 下载: chromium-pepper-flash-version.fc28.x86_64.rpm 安装后重启浏览器 解 ...

  10. swift是强类型语言

    swift是强类型语言 所有的变量必须先声明,后使用: 指定类型的变量只能接收类型与之匹配的值. 强类型:变量的类型明确,变量的赋值必须符合类型约束:变量的类型转化必须显式进行. 强类型:类型规则的制 ...