【代理模式】
描述:给某一个对象提供一个代理,并由代理对象控制对原对象的引用。
在一些情况下,一个客户不想 或者不能够直接 引用一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。举几个例子,用户提供食材和菜名,“不想”自己做菜,给厨师,厨师就是一个代理。国内用户访问facebook会被墙,代理可以绕开GFW并将请求结果返回。
例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 public interface IRequest { string Request (string sourceIp,string targetIp ) ; } class GFW : IRequest { public string Request (string sourceIp, string targetIp ) { if (sourceIp=="国内ip" && targetIp == "敏感ip" ) { return "404错误" ; } else { return "请求成功" ; } } } class Proxy : IRequest { GFW gfw = new GFW(); public string Request (string sourceIp, string targetIp ) { sourceIp = "代理ip" ; return gfw.Request(sourceIp, targetIp); } } GFW gfw = new GFW(); Console.Write(gfw.Request("国内ip" , "敏感ip" ));
简单来说代理模式能够保护请求者信息,能够解决请求者不能直接获取目标信息的问题。
【观察者模式】
描述:当事物的状态发生改变时,观察者通知主体。
熟悉mvvm的人肯定对观察者模式有比较深入的了解了,就是后台处理事务,然后通知用户界面显示。可以理解成一个监听的过程。但从oop角度来说,要将观察者和主体分离开来从而提高程序可维护性。在这个模式中观察者都会给其他主体的对象提供一个接口,通过这个接口,就可以让观察者获知该对象的状态。举个例子,老板不在办公室,所以有的人在炒股,有的人在看视频,有的人在玩游戏,然后前台放哨,只要老板回来,就通知大家。然后炒股的关闭看盘软件,看视频的退出浏览器,玩游戏的下线。
例子:
如果不用观察者模式,最原始的办法可能是:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 public class Receptionist { public void BossComeBack () { Console.Write("老板回来了!" ); new Share().CloseSoftWare(); new Video().CloseWebBrowser(); new Game().Logoff(); } } public class Share { public void CloseSoftWare () { Console.Write("关闭软件!" ); } } public class Video { public void CloseWebBrowser () { Console.Write("退出浏览器!" ); } } public class Game { public void Logoff () { Console.Write("游戏下线!" ); } }
这种方法从oop角度来说是很混乱且不利于扩展,如果还有其他同事需要前台通知,就要不断的修改Receptionist的BossComeBack方法。这违背了开闭原则。
下面用观察者模式来搭建这个模型:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 interface ISubject { void Notify () ; void Regiester (IObservable o ) ; void UnRegiester (IObservable o ) ; } class Receptionist : ISubject { private IList<IObservable> observers = new List<IObservable>(); public void Notify () { foreach (IObservable o in observers) { o.Action(); } } public void Regiester (IObservable o ) { if (o != null || !observers.Contains(o)) { observers.Add(o); } } public void UnRegiester (IObservable o ) { if (observers != null && observers.Contains(o)) { observers.Remove(o); } } public void BossComeBack () { Console.WriteLine("老板回来了!" ); Notify(); } } interface IObservable { void Action () ; } class Share : IObservable { public void Action () { Console.WriteLine("关闭软件!" ); } } class Video : IObservable { public void Action () { Console.WriteLine("退出浏览器!" ); } } class Game : IObservable { public void Action () { Console.WriteLine("游戏下线!" ); } } Video v = new Video(); Game g = new Game(); Share s = new Share(); Receptionist r = new Receptionist(); r.Regiester(v); r.Regiester(g); r.Regiester(s); r.BossComeBack();
上面这个例子满足了开闭原则,同时观察者和主体之间通过注册和撤销注册来建立关联。也满足了高内聚低耦合的特性。