天天看點

筆記、1:設計模式:觀察者模式

為了更清楚了的了解Angular中Http請求相關的 ObservAble與Subscribe,寫此筆記,備忘、回顧。

相關連結:
觀察者模式
Observable詳解
觀察者模式和釋出/訂閱模式的差別
察者模式與釋出/訂閱模式差別
觀察者模式與釋出/訂閱模式的差別
C#設計模式(一)訂閱-釋出模式
設計模式之美:Observer(觀察者)。執行個體
  1. 觀察者模式

    當對象間存在一對多關系時,則使用觀察者模式(Observer Pattern)。比如,當一個對象被修改時,則會自動通知它的依賴對象。觀察者模式屬于行為型模式。

    觀察者模式又叫釋出訂閱模式(Publish/Subscribe),二者有差別參見以上連結,它定義了一種一對多的關系,讓多個觀察者對象同時監聽某一個主題對象,這個主題對象的狀态發生變化時就會通知所有的觀察者對象,使得它們能夠自動更新自己。
               
  2. 意圖:定義對象間的一種一對多的依賴關系,當一個對象的狀态發生改變時,所有依賴于它的對象都得到通知并被自動更新。
  3. 主要解決:一個對象狀态改變給其他對象通知的問題,而且要考慮到易用和低耦合,保證高度的協作。
  4. 何時使用:一個對象(目标對象)的狀态發生改變,所有的依賴對象(觀察者對象)都将得到通知,進行廣播通知。
  5. 如何解決:使用面向對象技術,可以将這種依賴關系弱化。
  6. 關鍵代碼:在抽象類裡有一個 ArrayList 存放觀察者們。
  7. 執行個體: 1、拍賣的時候,拍賣物為梵高的 向日葵(Subject),拍賣師(觀察者Observer)觀察最高标價,然後通知給其他競價者(Client)競價。

    ::對照着觀察者模式可以這樣描述:所有的競價者(Client)依賴 梵高的向日葵(Subject,競拍同一件物品),拍賣師(觀察者Observer)觀察到有出高價的 就通知所有的競價者,競價者收到通知更新自己的最低起拍價。哪些人是競價者?要有名單記錄,記錄成這個樣子:

    1. Client1=拍(訂閱Subscribe)=>梵高的向日葵
    2. Client2=拍(訂閱Subscribe)=>梵高的向日葵
    3. Client3=拍(訂閱Subscribe)=>梵高的向日葵
    4. Client4=拍(訂閱Subscribe)=>畢加索最後自畫像
    5. Client5=拍(訂閱Subscribe)=>畢加索最後自畫像
    6. Client6=拍(訂閱Subscribe)=>梵高的向日葵
    
    上面的記錄記為:Client1、Client2、Client3、Client6 訂閱(Subscribe)了梵高的向日葵(Subject,被觀察者),起拍價100W(狀态)。梵高的向日葵的狀态一變化(Client拍價120W),拍賣師發現梵高的向日葵價格有變化(Subject狀态改變)立即通知(Notify)所有競價者(觀察者Observer:Client1、Client2、Client3、Client6)有新的起拍價,這些競價者們(觀察者Observer)必須更新自己的資訊(起拍價120W)。
    拍賣師要通知(Notify)所有的競價者(觀察者Observer),拍賣師又怎麼知道梵高的向日葵(Subject)狀态改變了?需要有一個觸發機制:向日葵的目前價格(屬性),屬性一旦變化(set),拍賣師立馬做出響應=>通知(notify)所有的觀察者。觀察者們更新自己的資訊。
    這樣了解觀察者模式就清楚了。Client Subscribe Subject,Subject State Changed then Notify Observer,and then Observer Publish Subject's new state to Client,Client update itself's State .
               
  8. 以上已經分不清觀察者模式 還是 釋出-訂閱模式 了,直接上别人的栗子吧。

    實作:執行個體

    1. 貓叫了
    2. 所有老鼠聽到叫聲,知道是哪隻貓來了
    3. 老鼠們逃跑,邊逃邊喊:”xx貓來了,快跑啊!我是老鼠xxx”

參照 上面貓和老鼠 改編拍賣 執行個體:

拍賣C#代碼實作

筆記、1:設計模式:觀察者模式
筆記、1:設計模式:觀察者模式
class Program
    {
        static void Main(string[] args)
        {
            //拍賣物
            拍賣物 拍賣物 = new 拍賣物("梵高的向日葵",);
            //登記 拍賣物 與 競價者
            競價者 競價者 = new 競價者("張珊", 拍賣物拍賣價);
            競價者 競價者 = new 競價者("李思", 拍賣物拍賣價);
            競價者 競價者 = new 競價者("王武", 拍賣物拍賣價);
            //拍賣物拍賣價變化 關聯 競價者的 更新起拍價方法。
            拍賣物新起拍價 += new 拍賣物拍賣物起價變化eventHandler(競價者更新起拍價);
            拍賣物新起拍價 += new 拍賣物拍賣物起價變化eventHandler(競價者更新起拍價);
            拍賣物新起拍價 += new 拍賣物拍賣物起價變化eventHandler(競價者更新起拍價);
            拍賣物拍賣價 = 競價者舉牌();//舉牌,觸發拍賣價改變=>執行通知 競價者們。
        }
    }
           

競價者基類:競價者可以舉牌

public abstract class 競價者Base
    {
        public abstract int 舉牌(int price);
    }
           

競價者類:競價者 name、拍價、舉牌,更新拍賣物起拍價()

public class 競價者: 競價者Base
    {
        public 競價者()
        {
        }
        public string Name { get; set; }
        public int 拍價 { get; set; }
        public 競價者(string name, int price)
        {
            this.拍價 = price;
            this.Name = name;
        }

        public void 更新起拍價(object sender, 拍賣物起價改變event e)
        {
            Console.WriteLine(e.拍賣物Name + " 價格變了! 起拍價提高,["+this.Name+"]目前的拍價是:" + this.拍價.ToString()+",新起拍價:"+e.拍賣物拍賣價);
        }

        public override int 舉牌(int price)
        {
            this.拍價 = price;
            return price;
        }
    }
           

拍賣物:拍賣不name、起拍價,起拍價變化(Set)立即觸發方法【起拍價變化】==》觸發 拍賣物拍賣物起價變化eventHandler【新起拍價】(與拍價者【更新起拍價】方法關聯)

public class 拍賣物
    {
        public event 拍賣物拍賣物起價變化eventHandler 新起拍價;

        public 拍賣物()
        {
        }        
        /// <summary>
        /// 拍賣物名稱
        /// </summary>
        public string Name { get; set; }

        private int _拍賣價;
        public int 拍賣價 {
            get
            {
                return _拍賣價;
            }
            set
            {
                if (_拍賣價==)
                {
                    _拍賣價 = value;
                }
                else
                {
                    _拍賣價 = value;
                    起拍價變化();
                }
            }
        }
        public 拍賣物(string name,int price)
        {
            this.Name = name;
            this.拍賣價 = price;
        }
        public void 起拍價變化()
        {
            Console.WriteLine("起拍價變化了!!");
            if (this.新起拍價 != null)
            {
                拍賣物起價改變event e = new 拍賣物起價改變event(this.Name,this.拍賣價);
                this.新起拍價(this, e);
            }
        }
    }
           

拍賣物拍賣物起價變化eventHandler:

public delegate void 拍賣物拍賣物起價變化eventHandler(object sender, 拍賣物起價改變event e);
           

拍賣物起價改變event:觸發拍賣價變化的事件,包含拍賣物資訊。

public class 拍賣物起價改變event : EventArgs
{
    private string _拍賣物Name;
    private int _拍賣物拍賣價;

    public 拍賣物起價改變event(string name,int price)
    {
        this.拍賣物Name = name;
        this._拍賣物拍賣價 = price;
    }

    public string 拍賣物Name
    {
        get
        { return _拍賣物Name; }
        set { this._拍賣物Name = value; }
    }

    public int 拍賣物拍賣價
    {
        get
        { return _拍賣物拍賣價; }
        set { this._拍賣物拍賣價 = value; }
    }
}
           

繼續閱讀