无废话C#设计模式之五:Prototype
2009-04-02 08:21:28 来源:WEB开发网意图
用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
场景
游戏场景中的有很多相似的敌人,它们的技能都一样,但是随着敌人出现的位置不同,这些人的能力不太一样。假设,我们现在需要把三个步兵组成一队,其中还有一个精英步兵,能力特别高。那么,你或许可以创建一个敌人抽象类,然后对于不同能力的步兵创建不同的子类。然后,使用工厂方法等设计模式让调用方依赖敌人抽象类。
问题来了,如果有无数种能力不同步兵,难道需要创建无数子类吗?还有,步兵模型的初始化工作是非常耗时的,创建这么多步兵对象可能还会浪费很多时间。我们是不是可以通过只创建一个步兵原型,然后复制出多个一摸一样的步兵呢?复制后,只需要调整一下这些对象在地图上出现的位置,或者调整一下它们的能力即可。原型模式就是用来解决这个问题的。
示例代码
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<Enemy> enemyGroup = gs.CreateEnemyGroup(enemyPrototype);
foreach (FootMan ft in enemyGroup)
{
ft.ShowInfo();
ft.FootmanAttack();
}
Console.WriteLine(sw.ElapsedMilliseconds);
}
}
class GameScene
{
public List<Enemy> CreateEnemyGroup(Enemy enemyPrototype)
{
List<Enemy> enemyGroup = new List<Enemy>();
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");
}
}
}
更多精彩
赞助商链接