网站首页

家园论坛

老版论坛

家园博客

业界新闻

技术文档

下载中心

速查中心

图片中心

硬件资讯
上一篇:无废话C#设计模式之四:Factory Method 下一篇:无废话C#设计模式之六:Builder
无废话C#设计模式之五:Prototype

来源: 作者: 添加日期:2007-12-2 10:28:34 点击次数:

意图

 

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

 

场景

 

       游戏场景中的有很多相似的敌人,它们的技能都一样,但是随着敌人出现的位置不同,这些人的能力不太一样。假设,我们现在需要把三个步兵组成一队,其中还有一个精英步兵,能力特别高。那么,你或许可以创建一个敌人抽象类,然后对于不同能力的步兵创建不同的子类。然后,使用工厂方法等设计模式让调用方依赖敌人抽象类。

       问题来了,如果有无数种能力不同步兵,难道需要创建无数子类吗?还有,步兵模型的初始化工作是非常耗时的,创建这么多步兵对象可能还会浪费很多时间。我们是不是可以通过只创建一个步兵原型,然后复制出多个一摸一样的步兵呢?复制后,只需要调整一下这些对象在地图上出现的位置,或者调整一下它们的能力即可。原型模式就是用来解决这个问题的。

 

示例代码

 

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");

        }

    }

}

 

本新闻共3页,当前在第1页  1  2  3  

 
设为首页 | 加入收藏 | 业务办理 | 友情链接 | 论坛版面 | 浙ICP备07502118号 |