• 多播委托与观察者模式联合使用,以及委托与事件的区别


    首先我们先看一下多播委托:

    使用委托时,首先我们声明委托,委托语法一共有四种类型,分别时有参,无参,以及有无参数返回值。

    1   public class DelegateShow //: System.MulticastDelegate,多播委托
    2     {
    3         public delegate void NoReturnNoPara();//1 声明委托  一个没有方法体的方法,加上delegate关键字
    4         public delegate void NoReturnWithPara(Student student, int size, string remark);
    5         public delegate string WithReturnNoPara();
    6         public delegate Student WithReturnWithPara(string name, int id);
    View Code

    接下来,我们写一个无参的方法:

    1  private void ShowNothing()
    2         {
    3             Console.WriteLine("This is ShowNothing");
    4         }
    View Code

    哦,对了,还要在顶类里面定义下方法,方便后面调用:

     public class OtherClass
        {
            public void ShowNothing()
            {
                Console.WriteLine("This is ShowNothing");
            }
    
            public static void ShowNothingStatic()
            {
                Console.WriteLine("This is ShowNothing");
            }
        }
    View Code

    好,接下来,我们开始委托实例化,调用委托:

     1   OtherClass otherClass = new OtherClass();
     2 
     3                 //多播委托就是一个方法列表  +=在列表尾巴上加方法,   
     4                 //-=就是从尾巴开始匹配,只移除第一个完全吻合方法,如果没有吻合,不报错
     5                 NoReturnNoPara method = new NoReturnNoPara(ShowNothing);//放入ShowNothing
     6                 method += otherClass.ShowNothing;//再放入2    
     7                 method += OtherClass.ShowNothingStatic;//再放入3
     8                 method += OtherClass.ShowNothingStatic;//再放入3
     9                 method += OtherClass.ShowNothingStatic;//再放入3
    10                 method += () => Console.WriteLine("123456");
    11                 method.Invoke();
    12 
    13                 //method.BeginInvoke(null, null);//多播委托不能直接异步
    14                 foreach (NoReturnNoPara item in method.GetInvocationList())
    15                 {
    16                     item.BeginInvoke(null, null);
    17                 }
    18 
    19                 Console.WriteLine("***********************************************");
    20                 method -= ShowNothing;
    21                 method -= otherClass.ShowNothing;//减少2
    22                 method -= OtherClass.ShowNothingStatic;//减少3
    23                 method -= () => Console.WriteLine("123456");
    24                 method.Invoke();
    25                 Console.WriteLine("***********************************************");
    View Code

    说一下:个人觉得多播委托,就是以事件为参数放到多播委托这个列表里面,放到列表的语法就是+=,从列表移除的方法就是-=,但是多播委托是不支持异步的,所以这里我们就要

    调用一个封装的参数method.GetInvocationList(),配合BeginInvoke()就可以实现多播委托异步。

    还有一个知识点就是,多播委托为变量配合lambda使用时,多个返回值只能返回最后一个值:

    1  WithReturnNoPara method = () => DateTime.Now.ToString();
    2                 Console.WriteLine(method.Invoke());
    3 
    4                 method += () => "1";
    5                 method += () => "2";
    6                 method += () => "3";
    7                 method += () => "4";
    8                 method += () => "5";
    9                 Console.WriteLine(method.Invoke());//待返回值的多播委托,只能获得最后一个方法的返回值
    View Code

    好了,接下来我们说一下观察者模式,这里我拷贝了一下观察者模式具体是一个什么样的业务场景。

    观察者模式(Observer)完美的将观察者和被观察的对象分离开。举个例子,用户界面可以作为一个观察者,业务数据是被观察者,用户界面观察业务数据的变化,发现数据变化后,就显示在界面上。面向对象设计的一个原则是:系统中的每个类将重点放在某一个功能上,而不是其他方面。一个对象只做一件事情,并且将他做好。观察者模式在模块之间划定了清晰的界限,提高了应用程序的可维护性和重用性。
    观察者设计模式定义了对象间的一种一对多的依赖关系,以便一个对象的状态发生变化时,所有依赖于它的对象都得到通知并自动刷新。
    额,这个是百度出来的意义,具体我举一个例子:例子就是猫、狗、小孩、老鼠,由于猫的一个动作发生的一起连锁反应。
    如果单纯实现功能,方法有很多,或许我们可以这样写:
     1   public class Cat
     2     {
     3         public void Miao()
     4         {
     5             Console.WriteLine("猫 miao了一声。。。");
     6 
     7 
     8             Dog.Wang();
     9             Mouse.Run();
    10             People.Awake();
    11             Stealer.Hide();
    12             Baby.Cry();
    13         }
    View Code

    这样确实可以实现功能,但是这样带来了很多不好的地方,如果以后我们再增加观察者或者修改观察者的动作,都会破坏当前这个方法,也违背了单一职责,耦合比较高,难维护等缺点,这时,就用到了我们委托来解偶啦。

    具体来看代码:

     1       public delegate void CatMiaoDelegate(); //声明委托;
     2         public CatMiaoDelegate CatMiaoDelegateHandler;
     3         public void MiaoDelegate()
     4         {
     5             Console.WriteLine("猫 MiaoDelegate了一声。。。");
     6             if (CatMiaoDelegateHandler != null)
     7             {
     8                 CatMiaoDelegateHandler.Invoke(); //实现委托;
     9             }
    10 
    11         }
    12           
    View Code
                    Cat cat = new Cat();
                    cat.Miao();
    
    
                    cat.CatMiaoDelegateHandler += Mouse.Run;
                    cat.CatMiaoDelegateHandler.Invoke();
                    cat.CatMiaoDelegateHandler = null;
    
                    cat.CatMiaoDelegateHandler += Dog.Wang;
                    cat.CatMiaoDelegateHandler += People.Awake;
                    cat.CatMiaoDelegateHandler += Stealer.Hide;
                    cat.CatMiaoDelegateHandler += Baby.Cry;
                    cat.CatMiaoDelegateHandler += Brother.Turn;
                    cat.MiaoDelegate();//多播委托调用实现其他类方法;
    View Code

    这样我们就把前面那个高耦合的方法中,得到了解耦的目的,并且在维护和增加其他观察者时不用再次破坏方法,符合对扩展开放  对修改封闭的原则,这样是极好的。

    接下来再说一下委托和事件的区别把:

    1、事件是委托的实例,加了一个event的关键字
    2、委托是一种类型 事件是委托的实例
    3、加event关键字后,控制了权限,不让外部调用或者直接赋值

    好了,上面个人总结对多播委托与观察者综合使用,以及委托与事件之间的区别。可能还有不对的地方,希望大牛多多指导。

     
  • 相关阅读:
    QTreeWidget创建
    Qt QTreeWidget节点的添加+双击响应+删除详解(转)
    Qt QTreeWidget 树形结构实现(转)
    QMessageBox类学习:
    QAction类详解:
    Qt事件和信号的区别 .
    Qt消息机制和事件(二)
    Qt消息机制和事件(一)
    初步开始学习图
    图中最短路径算法(Dijkstra算法)(转)
  • 原文地址:https://www.cnblogs.com/renzhitian/p/6080751.html
Copyright © 2020-2023  润新知