委托和事件

观察者模式:有时又被称为发布订阅模式;
委托:把动作放到外面,由你传进来;
缓存:一般都有过期策略,也可以不设置过期时间;
查询数据--》访问数据源--》判断缓存是否为空==为空?查询获取数据源--》将数据源插入内存--》返回数据:返回数据
更大的并发:负载均衡:把一模一样的东西拷到N台机器上,来访问,把访问平均分到N台机器上;解决高并发
分布式缓存:需要缓存的数据非常大,一台机器上放不下,需要一种算法放到N台机器上,访问的时候就像访问一台机器上;高可用和扩充
function()系统自定义的委托,返回一个参数;
action()系统自定义的委托,无返回的;
委托:把方法当作参数传递;
开闭原则:对扩展开放,对修改封闭;
事件:是一种特殊的委托;事件是一个语法堂:减少许多代码的编写;
事件比委托安全:委托可以被覆盖;在代码中事件只能出现在+=、-=的左边
委托:把方法当作参数传递,是一种开闭原则的思想,把动作放出去,内部进行封装,外部进行绑定,当动作发生变化的时候,内部不发生任何的变化;
事件:是一个特殊的委托,这和事件的安全性有关,事件是不可以被覆盖的,委托可以被覆盖,当多播(委托附加多个方法)的情况下,他是可以被覆盖的,覆盖以后,附加的事件也会被覆盖掉,有安全隐患,事件是不会被覆盖掉的,其实事件的原理就是一个委托,如果进行反编译就会看到,他的里面有一个私有的委托,还有一个添加和删除的委托的方法;
review:代码审核
 
1、例子(一般的方法)
 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace First
{
    public class BugManager
    {
        /// <summary>
        /// 发生bug的方法
        /// </summary>
        /// <returns></returns>
        public void BugMonitor()
        {
            //监听bug开始
            //此处省略代码1万行
            //发生bug
            SendEmail();//发送邮件
           SendSms();//发送短信
           Electric();
            //发送完毕的业务代码开始
            //此处省略代码1千行
            //发送完毕的业务代码结束
        }
        /// <summary>
        /// 发邮件
        /// </summary>
        public void SendEmail()
        {
            Console.WriteLine("发送邮件给刘森!");
            Console.WriteLine("发送邮件给杨志威!");
        }
 
       
        /// <summary>
        /// 发短信
        /// </summary>
        public void SendSms()
        {
            Console.WriteLine("发送短信给刘森!");
            Console.WriteLine("发送短信给杨志威!");
        }

        public void Electric()
        {
            Console.WriteLine("电击刘森!");
            Console.WriteLine("电击杨志威!");
        }
    }
}

2、例子(委托的方法)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Old
{
    public class OldBugManager
    {
        /// <summary>
        /// 发送委托
        /// </summary>
        public delegate void SendDelegate();
        /// <summary>
        /// 发送的委托实例
        /// </summary>
        public SendDelegate OldSendEvent;
        /// <summary>
        /// 监听bug的方法
        /// </summary>
        public void OldBugMonitor()
        {
            //监听bug开始
            //此处省略代码1万行
            //发生bug
            if (OldSendEvent != null)
            {
                OldSendEvent();
            }
            //发送完毕的业务代码开始
            //此处省略代码1千行
            //发送完毕的业务代码结束
        }
    }
}
电击类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Old
{
    public class Electric
    {
        public void ElectricExec()
        {
            Console.WriteLine("电击刘森!");
            Console.WriteLine("电击杨志威!");
        }
    }
}
发送邮件
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Old
{
    public class EMail
    {
        /// <summary>
        /// 发邮件
        /// </summary>
        public void SendEmail()
        {
            Console.WriteLine("发送邮件给刘森!");
            Console.WriteLine("发送邮件给杨志威!");
        }
    }
}
3、例子(事件的方法)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Second
{
    public class BugManager
    {
        /// <summary>
        /// 发送委托
        /// </summary>
        public delegate void SendDelegate();
        /// <summary>
        /// 发送事件
        /// </summary>
        public event SendDelegate SendEvent;
        /// <summary>
        /// 监听bug的方法
        /// </summary>
        public void BugMonitor()
        {
            //监听bug开始
            //此处省略代码1万行
            //发生bug
            if (SendEvent != null)
            {
                SendEvent();
            }
             //发送完毕的业务代码开始
            //此处省略代码1千行
            //发送完毕的业务代码结束
        }
    }
}
电击类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Old
{
    public class Electric
    {
        public void ElectricExec()
        {
            Console.WriteLine("电击刘森!");
            Console.WriteLine("电击杨志威!");
        }
    }
}
发送邮件
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Old
{
    public class EMail
    {
        /// <summary>
        /// 发邮件
        /// </summary>
        public void SendEmail()
        {
            Console.WriteLine("发送邮件给刘森!");
            Console.WriteLine("发送邮件给杨志威!");
        }
    }
}
4、例子 事件比委托安全(为什么用事件不用委托)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Old
{
    class Program
    {
        static void Main(string[] args)
        {
            EMail email = new EMail();
            Electric electric = new Electric();
            #region 优化前
            //OldBugManager oldBugManager = new OldBugManager();
            //oldBugManager.OldSendEvent += new OldBugManager.SendDelegate(electric.ElectricExec);
            //oldBugManager.OldSendEvent += new OldBugManager.SendDelegate(email.SendEmail);
          
            //#region 引发的问题
            ////这样做引发的问题 开始
            ////   oldBugManager.OldSendEvent = new OldBugManager.SendDelegate(MakeTrouble); //1 因为委托暴露所以可以在外部重写
            ////     oldBugManager.OldSendEvent.Invoke();   // 2  我可以跳过流程直接执行
            ////结束
            //#endregion
            //oldBugManager.OldSendEvent = new OldBugManager.SendDelegate(MakeTrouble);
            //    oldBugManager.OldSendEvent();  //监听bug方法
            #endregion
 
        //    #region 优化后
            OptimizeBugManager optimizeBugManager = new OptimizeBugManager();

            optimizeBugManager.AddSendDelegate(new OptimizeBugManager.SendDelegate(email.SendEmail));
            optimizeBugManager.AddSendDelegate(new OptimizeBugManager.SendDelegate(electric.ElectricExec));
            optimizeBugManager.AddSendDelegate(new OptimizeBugManager.SendDelegate(MakeTrouble));
            optimizeBugManager.RemoveSendDelegate(new OptimizeBugManager.SendDelegate(MakeTrouble));
            //    optimizeBugManager._OptimizeSendEvent = new OldBugManager.SendDelegate(MakeTrouble);   //因为委托是私有的,所以无法重写
            //   optimizeBugManager._OptimizeSendEvent.Invoke();  //无法跳过流程直接执行
            optimizeBugManager.OldBugMonitor();
        //    #endregion
 
           
 

            Console.ReadLine();
        }
        /// <summary>
        /// 捣乱的方法
        /// </summary>
        public static void MakeTrouble()
        {
            Console.WriteLine("我就不发邮件,怎么地?");
        }

    }
}
电击类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Old
{
    public class Electric
    {
        public void ElectricExec()
        {
            Console.WriteLine("电击刘森!");
            Console.WriteLine("电击杨志威!");
        }
    }
}
发送邮件
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Old
{
    public class EMail
    {
        /// <summary>
        /// 发邮件
        /// </summary>
        public void SendEmail()
        {
            Console.WriteLine("发送邮件给刘森!");
            Console.WriteLine("发送邮件给杨志威!");
        }
    }
}
5、例子(没有事件的时候通过私有化委托来避免被覆盖,结合第4个例子看)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Old
{
    public class OptimizeBugManager
    {
        /// <summary>
        /// 发送委托
        /// </summary>
        public delegate void SendDelegate();
        /// <summary>
        /// 发送委托
        /// </summary>
        private SendDelegate _OptimizeSendEvent;
        /// <summary>
        /// 添加订阅者
        /// </summary>
        /// <param name="sendDelegate"></param>
        public void AddSendDelegate(SendDelegate sendDelegate)
        {
            if (sendDelegate != null)
            {
                if (_OptimizeSendEvent != null)
                {
                    _OptimizeSendEvent += sendDelegate;
                }
                else
                {
                    _OptimizeSendEvent = sendDelegate;
                }
            }
          
        }
        /// <summary>
        /// 移除订阅者
        /// </summary>
        /// <param name="sendDelegate"></param>
        public void RemoveSendDelegate(SendDelegate sendDelegate)
        {
            if (sendDelegate != null)
            {
                if (_OptimizeSendEvent != null)
                {
                    _OptimizeSendEvent -= sendDelegate;
                }
            }
        }
        /// <summary>
        /// 监听bug的方法
        /// </summary>
        public void OldBugMonitor()
        {
            //监听bug开始
            //此处省略代码1万行
            //发生bug
            if (_OptimizeSendEvent != null)
            {
                _OptimizeSendEvent();
            }
            //发送完毕的业务代码开始
            //此处省略代码1千行
            //发送完毕的业务代码结束
        }
    }
}
原文地址:https://www.cnblogs.com/wpchina/p/10738345.html