1. 程式人生 > >委託,瞭解釋出者訂閱者模型

委託,瞭解釋出者訂閱者模型

一。釋出者訂閱者模型圖解。

在這裡插入圖片描述
從圖中我們看有一個部分組成?

  1. 釋出者
  2. 訂閱者
  3. 事件繫結
  4. 事件資訊
    3,4部分容易混為一談,我們這裡做一個例子用於理解:
    要是實現A->B貨物的運輸,需要什麼呢?需要一條能通的道路,還需要一輛運載了貨物的車。A此時就是釋出者,B是訂閱者,事件繫結就是一條能通的道路,事件資訊就是這個運載了貨物的車。如果只有事件繫結(道路)而沒有事件資訊(貨物車),就沒有可以傳輸的東西了。

二。C#中委託和事件的命名規範。

  1. 什麼是事件?和委託指標有區別嗎?
    我認為並沒有,都可以指向多個函式。
    命名語法:public event delegate 事件名;
    與普通的委託指標多了個event
  2. 委託的命名規範:委託就是為了建立事件(委託指標),因此它的名字要根據事件名來設計通常是事件名Handler
  3. 事件資訊:這是一個不同於釋出者和訂閱者的類,通常他繼承EventArgs。
  4. .net桌面應用應用中經常使用的委託就是(object sender,EventArgs e)
    <1>前一個引數表示訊息的釋出者
    <2>後一個引數表示訊息的具體內容。

三。通過一個例項來解析這個模型。

  1. 我們將嚴格按照模型進行分佈講解
    背景:
    <1>建立一個”憨有錢“銀行的一個賬戶物件,賬戶的號碼是12345678910。
    <2>建立一個手機物件,有手機號123456789,建立郵箱物件有郵箱號碼

    [email protected]
    <3>起初這些物件沒有什麼關係,但是可以通過建立物件後使用事件繫結的方法實現:在賬戶物件中取錢,會向這個手機和郵箱裡面傳送取款訊息。

  2. 例項剖析
    <1>按照上面的模型建立物件
    釋出者:銀行賬戶
    訂閱者:手機,郵箱
    事件繫結:通過銀行賬戶物件的委託事件與手機訊息,郵件訊息繫結。
    事件訊息:每次交易時產生,銀行賬戶釋出,在各個物件之間傳遞
    <2>通過釋出者物件內部啟動事件
    <3>訂閱者按道理應該會接收到訊息

3.我們按過程寫類。
<1>訊息類:交易資訊

public class UserEventArgs :
EventArgs //事件的資訊類,這個類需要繼承EnventArg並且以EnvenArg結尾 { public readonly string amount; public string time; public UserEventArgs(string amount) { this.amount = amount; this.time = System.DateTime.Now.ToString();//獲取當前交易的事件 } }

<2>釋出者:銀行賬戶類

//釋出者,也就是被監視的物件-銀行賬號
    class BankAccount:object
    {
        static public readonly string bankname = "憨有錢銀行";
        //本銀行的名字是對所有的賬戶都相同的
        public string accountnumber;
        public BankAccount(string accountnumber)//建構函式,寫入賬戶號碼
        { this.accountnumber = accountnumber; }
        public override string ToString()//重寫object的ToString方法。
        { return bankname + "向賬戶" + accountnumber + "發出提醒:"; }

        //宣告一個處理銀行交易的委託,委託的名字應該是 事件名handler
        //委託的引數必須是有一個訊息傳送者,訊息內容
        public delegate void ProcessTranEventHandler(object sender, UserEventArgs e);
        //宣告一個事件
        public event ProcessTranEventHandler ProcessTran;
        protected virtual void OnProcessTran(UserEventArgs e)
        {
            if (ProcessTran != null)
            {
                ProcessTran(this, e);
            }
        }
        //很多人會問,直接把事件放在Peocess函式中不就行了?不是更簡單嗎?
        //其實這裡為類的擴充套件做了準備,如果

<3>訂閱者:手機,郵箱類

//訂閱者Email
    class Email
    {
        private string emailaddress;
        public Email(string emailaddress)//建構函式初始化
        { this.emailaddress = emailaddress; }
        public  void SendEmail(object sender, UserEventArgs e)
        {
            Console.WriteLine(sender.ToString());
            Console.WriteLine("向您的郵箱" + this.emailaddress + "傳送郵件:");
            Console.WriteLine("\t 您在" + e.time + "取款金額為" + e.amount);
        }
    }

    //訂閱者手機
    class Mobile
    {
        public string mobilenumber;
        public Mobile(string mobilenumber)
        { this.mobilenumber = mobilenumber; }
        public  void SendNotification(object sender, UserEventArgs e)
        {
            Console.WriteLine(sender.ToString());
            Console.WriteLine("向用戶手機" + this.mobilenumber + "傳送簡訊:");
            Console.WriteLine( "\t您在" + e.time + "取款金額為" + e.amount);
        }
    }

<4>事件繫結類

    //訂閱系統,實現銀行系統訂閱幾個Observer,實現與客戶端的耦合
    class SubscribSystem
    {
        public  SubscribSystem(BankAccount bankAccount,Mobile mobile_object,Email email_object)
        {
            //現在我們在銀行賬戶訂閱2個,分別是電子郵件和手機簡訊
            bankAccount.ProcessTran += new BankAccount.ProcessTranEventHandler(email_object.SendEmail);
            bankAccount.ProcessTran += new BankAccount.ProcessTranEventHandler(mobile_object.SendNotification);
        }
    }

<5>主函式:產生交易,並且傳達訊息

       public static void Main(string[] args)
        {
            //首先建立一個賬戶釋出者物件
            BankAccount my_account = new BankAccount("12345678910");
            //兩個訂閱者物件
            Mobile my_mobile = new Mobile("123456789");
            Email my_email = new Email("[email protected]");
            //把這個釋出者物件和訂閱者物件進行繫結,傳入繫結系統物件中。
            //按順序傳入
            SubscribSystem my_subscibSystem = new SubscribSystem(my_account, my_mobile, my_email);



            Console.Write("請輸入您要取款的金額:");
            string amount = Console.ReadLine();
            Console.WriteLine("交易成功,請取磁卡。\n");
            //初始化e事件資訊
            UserEventArgs user = new UserEventArgs( amount);//產生一個事件的訊息
            //在銀行賬戶中觸發這個事件
            my_account.Process(user);
            Console.ReadKey();
        }
    }

<6>執行檢查,成功

在這裡插入圖片描述