这几个模式比较相似, 都是用做interface, 但有所不一样
Proxy, 特色是以假乱真, client在使用的时候就和在使用真正的object同样, 接口彻底一致, proxy和object的交互是对client透明的
Adapter, 典型的是电源的adapter, 美标换欧标, 即解决接口不匹配, client和lib都已经写好, 但接口不匹配
Facade, 用于屏蔽子系统的细节, 提供高层接口层
Mediator, 典型的房产中介, 当对象之间关系复杂的时候, 避免对象之间的直接沟通web
其中Adapter和Facade是在不得已的状况下采用的, 即已有legacy的系统, 很难改变的状况下的折衷方案网络
代理(Proxy)模式给某一个对象提供一个代理,并由代理对象控制对原对象的引用。
场景, 在软件系统中,有些对象有时候因为跨越网络或者其余的障碍,而不可以或者不想直接访问另外一个对象.
这个模式很容易理解, 并且实际应用不少, 如
远程(Remote)代理, 典型的例子, webservice远程调用, RPC
保护(Protect or Access)代理, 控制访问权限
虚拟(Virtual)代理, 当建立消耗资源很大的对象时使用, 如打开不少图片的Html, 会先显示文字, 而图片会下载结束后才显示, 那些未打开的图片框就是用虚拟代理来替代真实图片.
智能引用(Smart Reference)代理:代理须要处理一些额外的事, 如引用计数, 计数为0时释放引用等.
可见这个模式虽然简单, 可是仍是颇有用的, 代理提供了一层封装, 使客户在访问到真正对象前, 能够作预先的处理, 灵活性很大.ide
以下图, Subject类定义了RealSubject和Proxy公共的接口, 这样在任何使用RealSubject的地方均可以使用Proxy
this
class RealSubject : Subject { void Request() { print("Real request");} } class Proxy : Subject { RealSubject realSub; //真实对象 void request() { realSub.Request(); } //能够在访问真实对象时, 添加任何逻辑 }
用户使用直接访问代理
spa
Proxy p = new Proxy()
p.Request()
门面模式 (facade)又称外观模式, 为子系统中的一组接口提供一个一致的界面, Facade 模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。
这个模式很简单, 当子系统接口比较复杂时, 若是让客户直接使用子系统接口, 有以下问题,
系统难于使用, 客户须要先熟悉复杂的子系统接口
耦合度太高, 当子系统改变时, 会影响到客户类
这样明显违反了迪米特法则和依赖倒转法则, 因此咱们的作法就是提供一个相对简单的高层抽象接口来屏蔽底层子系统的细节,从而解决了上面两个问题.
这个模式很简单, 也很经常使用, 不管你是否知道这个模式设计
适配器模式 (Adapter), 将一个类的接口转换成客户但愿的另一个接口。Adapter模式使得本来因为接口不兼容而不能一块儿工做的那些类能够一块儿工做。
这个模式很简单, 通常用于对已有系统的porting和重用. 这个模式应该是不得已而为之, 由于直接改变原来系统的接口确定不合适, 因此为了能够重用这个系统必须增长一层adapter.3d
中介者模式(Mediator), 用一个中介对象来封装一系列的对象交互. 中介者使各对象不须要显式地相互引用, 从而使其耦合松散, 并且能够独立地改变它们之间的交互.代理
这个模式很好理解, 如房产中介, 留学中介, 固然最大的中介者,联合国. 中介的目的就是解耦合, 使得能够独立地改变和复用各个同事对象和中介者类. 对象
对于面向对象设计, 须要将系统分割成许多对象以增长复用性, 可是对象间激增的相互关联有大大下降了其复用性, 大量的关联致使对象间紧耦合, 修改一个对象就会致使全部和该对象相关联的对象的改动, 牵一发而动全身.
可是面对这种状况, 首先想到的不该该是用中介者模式, 而是系统设计不合理, 设计时应尽可能的高聚合低耦合, 而对象间大量的关联致使高耦合, 颇有多是设计不合理, 系统分割过细致使的, 通常经过从新设计就能够解决.
中介者模式适用于, 对象间关系确实很复杂, 如联合国, 各国间关系错综复杂, 因而须要一个中介者把对象间复杂的交换剥离出来交给中介者来处理.
这个模式的缺点就是, 因为把全部对象间交换集中在中介者, 会致使中介者逻辑会过于复杂.blog
class ConcreteMediator : Mediator { //中介者须要认识全部的同事对象 private ConcreteColleague1 colleague1; private ConcreteColleague2 colleague2; public override void Send(string message,Colleague colleague) { //根据各类条件在不一样的同事对象间经行交互 //这段逻辑每每会变的很复杂 if (colleague == colleague1) { colleague2.Notify(message); } else { colleague1.Notify(message); } } } class ConcreteColleague1 : Colleague { protected Mediator mediator; //同事对象只须要认识中介者, 而不须要认识其余任何同事 // Constructor public ConcreteColleague1(Mediator mediator) : base(mediator) { } public void Send(string message) { mediator.Send(message, this); //须要和其余同事交互时, 经过中介者 } public void Notify(string message) //提供给中介者的交互接口 { Console.WriteLine("Colleague1 gets message: "+ message); } } //客户代码 ConcreteMediator m = new ConcreteMediator(); ConcreteColleague1 c1 = new ConcreteColleague1(m); ConcreteColleague2 c2 = new ConcreteColleague2(m); m.Colleague1 = c1; m.Colleague2 = c2; c1.Send("How are you?"); c2.Send("Fine, thanks");