程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> 無廢話C#設計模式之五:Prototype(1)

無廢話C#設計模式之五:Prototype(1)

編輯:關於C語言

意圖

用原型實例指定創建對象的種類,並且通過拷貝這些原型創建新的對象。

場景

游戲場景中的有很多相似的敵人,它們的技能都一樣,但是隨著敵人出現的位置不同,這些人的能力不太一樣。假設,我們現在需要把三個步兵組成一隊,其中還有一個精英步兵,能力特別高。那麼,你或許可以創建一個敵人抽象類,然後對於不同能力的步兵創建不同的子類。然後,使用工廠方法等設計模式讓調用方依賴敵人抽象類。

問題來了,如果有無數種能力不同步兵,難道需要創建無數子類嗎?還有,步兵模型的初始化工作是非常耗時的,創建這麼多步兵對象可能還會浪費很多時間。我們是不是可以通過只創建一個步兵原型,然後復制出多個一摸一樣的步兵呢?復制後,只需要調整一下這些對象在地圖上出現的位置,或者調整一下它們的能力即可。原型模式就是用來解決這個問題的。

示例代碼

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

        }

    }

}

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved