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