全文预览已结束
下载本文档
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
无废话C#设计模式之五:Prototype意图用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。场景游戏场景中的有很多相似的敌人,它们的技能都一样,但是随着敌人出现的位置不同,这些人的能力不太一样。假设,我们现在需要把三个步兵组成一队,其中还有一个精英步兵,能力特别高。那么,你或许可以创建一个敌人抽象类,然后对于不同能力的步兵创建不同的子类。然后,使用工厂方法等设计模式让调用方依赖敌人抽象类。问题来了,如果有无数种能力不同步兵,难道需要创建无数子类吗?还有,步兵模型的初始化工作是非常耗时的,创建这么多步兵对象可能还会浪费很多时间。我们是不是可以通过只创建一个步兵原型,然后复制出多个一摸一样的步兵呢?复制后,只需要调整一下这些对象在地图上出现的位置,或者调整一下它们的能力即可。原型模式就是用来解决这个问题的。示例代码using System;using System.Threading;using System.Collections.Generic;using System.IO;using System.Runtime.Serialization.Formatters.Binary;using System.Diagnostics;namespace PrototypeExample class Program static void Main(string args) Stopwatch sw = new Stopwatch(); sw.Start(); Enemy enemyPrototype = new FootMan(5, 4, new Location(100, 200); GameScene gs = new GameScene(); List enemyGroup = gs.CreateEnemyGroup(enemyPrototype); foreach (FootMan ft in enemyGroup) ft.ShowInfo(); ft.FootmanAttack(); Console.WriteLine(sw.ElapsedMilliseconds); class GameScene public List CreateEnemyGroup(Enemy enemyPrototype) List enemyGroup = new List(); Enemy e1 = enemyPrototype.Clone(true); e1.Location.x = enemyPrototype.Location.x - 10; Enemy e2 = enemyPrototype.Clone(true); e2.Location.x = enemyPrototype.Location.x + 10; Enemy elite = enemyPrototype.Clone(true); elite.Power = enemyPrototype.Power * 2; elite.Speed = enemyPrototype.Speed * 2; elite.Location.x = enemyPrototype.Location.x; elite.Location.y = enemyPrototype.Location.y + 10; enemyGroup.Add(e1); enemyGroup.Add(e2); enemyGroup.Add(elite); return enemyGroup; Serializable class Location public int x; public int y; public Location(int x, int y) this.x = x; this.y = y; Serializable abstract class Enemy protected Location location; public Location Location get return location; set location = value; protected int power; public int Power get return power; set power = value; protected int speed; public int Speed get return speed; set speed = value; public abstract Enemy Clone(bool isDeepCopy); public abstract void ShowInfo(); public Enemy(int power, int speed, Location location) Thread.Sleep(1000); / Construct method is assumed to be a high calc work. this.power = power; this.speed = speed; this.location = location; Serializable class FootMan : Enemy private string model; public FootMan(int power, int speed, Location location) : base(power, speed, location) model = footman; public override void ShowInfo() Console.WriteLine(model:0 power:1 speed:2 location:(3,4), model, power, speed, location.x, location.y); public override Enemy Clone(bool isDeepCopy) FootMan footman; if (isDeepCopy) MemoryStream memoryStream = new MemoryStream(); BinaryFormatter formatter = new BinaryFormatter(); formatter.Serialize(memoryStream, this); memoryStream.Position = 0; footman = (FootMan)formatter.Deserialize(memoryStream); else footman = (FootMan)this.MemberwiseClone(); return footman; public void FootmanAttack() Console.WriteLine(FootmanAttack); 代码执行结果如下图:代码说明l Enemy类是抽象原型,它有两个用途,一是定义了原型的一些抽象内容,二是定义了原型模式必须的拷贝方法。在这里,我们看到,每个敌人的属性有位置、攻击力、速度等,并且能通过ShowInfo()方法来获取这个人的信息。l FootMan类就是具体原型了,它显示了敌人的具体参数以及实现了克隆自身。l GameScene类就是调用方,在这里我们并没有看到有和具体原因进行依赖,通过复制传入的克隆原型,得到一些新的敌人,在原型的基础上稍微调整一下就变成了一支敌人部队。l 原型模式通过对原型进行克隆来替代无数子类,因此也就减少了调用方和具体类型产生依赖的程序。l Clone()方法接受一个参数,表示是否是深拷贝。在这里,我们通过序列化反序列化实现深拷贝,深拷贝实现对象的完整复制,包括对象内部的引用类型都会复制一份全新的。在这里,如果3个敌人对象的Location都指向内存同一个地址的话,那么它们就分不开了,因此,在复制的时候需要进行深拷贝,使得它们的Location是独立的。l 在初始化Enemy的时候,我们Sleep()了一下,目的是模拟对象的创建是一个非常耗时的工作,这也体现了原型模式的另一个优势,在生成敌人的时候,我们其实无需再做这些工作了,我们只需要得到它的完整数据,并且进行一些修改就是一个新的敌人。l 运行程序后可以看到,虽然创建了三个敌人,但是只耗费了一个敌人的创建时间,三个敌人都是从原型克隆出来的。由于进行了深拷贝,修改了一个敌人的位置并不会影响其它敌人。何时采用l 从代码角度来说, 如果你希望运行时指定具体类(比如是使用Footman作为敌人还是使用其它),或者你希望避免创建对象时的初始化过程(如果这个过程占用的时间和资源都非常多),或者是希望避免使用工厂方法来实现多态的时候,可以考虑原型模式。l 从应用角度来说, 如果你创建的对象是多变化、多等级的产品,或者产品的创建过程非常耗时的时候(比如,有一定的计算量,或者对象创建时需要从网络或数据库中获取一定的数据),或者想把产品的创建独立出去,不想了解产品创建细节的时候可以考虑使用。不得不说,原型模式给了我们多一种创建对象,并且不依赖具体对象的选择。实现要点l .NET中使用Object的MemberwiseClone()方法来实现浅拷贝,通过序列化和反序列化实现深拷贝,后者代价比较大,选择何时的拷贝方式。l 原型模式同样需要抽象类型和具体类型,通过相对稳定的抽象类型来减少或避免客户端的修改可能性。l 在代码中,我们把敌人作为了抽象类型,抽象层次
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 标准版2024建设工程设计合同
- 2024年聘用副总经理合同书
- 无劳动合同证明的获取途径分析
- 2024年承包鱼塘合同范本
- 抵押短期借款合同格式
- 加工协议书撰写要点
- 柴油发动机控制柜技术规格书
- 土地流转合同补充协议2024年
- 建筑工程合同履约中的安全控制
- 业务经理聘请合同
- 北京市第四中学2024-2025学年七年级上学期期中生物学试题(含答案)
- 体育教师先进个人事迹材料
- 2025届江苏省苏州市第一中学物理高三第一学期期末学业水平测试模拟试题含解析
- 企业财务管理数字化转型实施方案
- 第九课+发展中国特色社会主义文化+课件高中政治统编必修四哲学与文化
- 牙用漂白凝胶市场环境与对策分析
- 2024年山东省济南市中考英语试题卷(含答案)
- 人教版七年级道德与法治上册 期中复习知识梳理
- 3.1 农业区位因素及其变化 课件 高一地理人教版(2019)必修第二册
- 建筑施工企业(安全管理)安全生产管理人员安全生产考试参考题及答案
- 锅炉应急预案演练方案
评论
0/150
提交评论