追蹤
兔子也會的遊戲設計
關於部落格
一個推廣XNA與OGRE的園地,當然還有其他關於遊戲設計的主題,歡迎有興趣的同好交流指教
  • 104845

    累積人氣

  • 0

    今日人氣

    0

    追蹤人氣

觀察者模式

//觀察者模式
using System;
using System.Collections;

namespace Observer
{
    ///
    /// Class1 的摘要描述。
    /// 主控台測試部分
    ///
    class Client
    {
        ///
        /// 應用程式的主進入點。
        ///
        [STAThread]
        static void Pause()
        {
            Console.WriteLine("Press Enter To Continue....");
            Console.ReadLine();
        }

        static void Main(string[] args)
        {
            //這是負責顯示正常模式的物件
            ShowNormal normal;
            //這是負責顯示特殊模式的物件
            ShowSpecial special;
            // 球員資料
            PlayerData playerData = new PlayerData();
            //現在我把球員資料給綁定到觀察者
            normal = new ShowNormal(playerData);
            //現在我把球員資料給綁定到另一個觀察者
            special = new ShowSpecial(playerData);
            //一但球員資料有所變更 就會通知之前綁定的觀察者 而依序顯示出來 如此可以鬆綁兩者之間的關係
            //這就是整個模式的關鍵 許多GUI也是用這種方式實做 一個當作listener 一但有所變更 立刻通知所有人
            //如此即可讓資料一次更新並做處理
            playerData.SetData("王大蠻", 100);
            //移除其中一個觀察者也沒問題
            normal.Destory();
            Pause();
        }
    }

    //觀察者介面
    interface Observer
    {
        void Update(string name, int skill);
        void Destory();
    }
    //把顯示的介面另外獨立出來 因為要針對介面寫程式
    interface Display
    {
        void Show();
    }

    //
    //實作觀察者與顯示介面
    //

    //正常顯示
    class ShowNormal : Observer, Display
    {
        private string playerName;
        private int playerSkill;
        private Subject subject;
        //將資料綁定 表示說向他註冊 有變更通知我
        public ShowNormal(Subject subject)
        {
            this.subject = subject;
            this.subject.Add(this);
        }
        //資料一但有變動就會呼叫這個更新
        public void Update(string name, int skill)
        {
            playerName = name;
            playerSkill = skill;
            //這放其他地方會更好
            Show();
        }
        //看要對資料做什麼處理 這裡暫時以顯示取代
        public void Show()
        {
            Console.WriteLine("我顯示正常格式");
            Console.WriteLine("使用者名稱" + playerName);
            Console.WriteLine("技能" + playerSkill);
            Console.WriteLine("");
        }
        //表示不要再綁定了 解除註冊
        public void Destory()
        {
            subject.Remove(this);
            Console.WriteLine("我ShowNormal被移除了n");
        }
    }

    //特出顯示
    class ShowSpecial : Observer, Display
    {
        private string playerName;
        private int playerSkill;
        private Subject subject;
        public ShowSpecial(Subject subject)
        {
            this.subject = subject;
            this.subject.Add(this);
        }
        public void Update(string name, int skill)
        {
            playerName = name;
            playerSkill = skill;
            Show();
        }
        public void Show()
        {
            Console.WriteLine("我顯示特殊格式");
            Console.WriteLine("使用者名稱*****" + playerName + "*******");
            Console.WriteLine("技能~~~~~~~" + playerSkill + "~~~~~~~");
            Console.WriteLine("");
        }
        public void Destory()
        {
            subject.Remove(this);
            Console.WriteLine("我ShowSpecial被移除了");
        }
    }

    //主題的介面 也就是可觀察的observable
    interface Subject
    {
        void Add(Object ob);
        void Notify();
        void Remove(Object ob);
    };

    //實作主題 假設是球員資料
    class PlayerData : Subject
    {
        private string playerName;
        private int playerSkill;
        ArrayList data;
        public PlayerData()
        {
            data = new ArrayList();
        }
        //別人註冊會呼叫這個
        public void Add(Object ob)
        {
            data.Add(ob);
        }
        //有變更就通知大家
        public void Notify()
        {
            for (int a = 0; a < data.Count; a++)
            {
                Observer observer = (Observer)data[a];
                observer.Update(playerName, playerSkill);
            }
        }
        //哪個想被移除就呼叫這個
        public void Remove(Object ob)
        {
            data.Remove(ob);
        }
        //資料變更的地方
        public void SetData(string name, int skill)
        {
            playerName = name;
            playerSkill = skill;
            Notify();
        }
    }
}

相簿設定
標籤設定
相簿狀態