委托,了解发布者订阅者模型

一。发布者订阅者模型图解。

在这里插入图片描述
从图中我们看有一个部分组成?

  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>运行检查,成功

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_44055272/article/details/85179227