外观模式(FACADE)
又称为门面模式
意图
为子系统中的一组接口提供一个一致的界面
Facade模式定义了一个高层接口,这一接口使得这一子系统更加易于使用。
意图解析
随着项目的持续发展,系统基本上都是会往功能更全面的方向发展,那么也就意味着咱们的系统将会变得更加复杂。
系统会被划分为多个单独的子系统,每一个子系统完成一部分功能,经过分工协做完成所有功能。
一个子系统也可能进一步拆分为更小的几个子系统。
程序中的文件将会愈来愈多,相互关联也会变得更加复杂
当使用一个功能的时候,做为客户端
你须要弄清楚相关类之间的关系,以及正确的调用顺序。
好比下图中
你须要本身识别有哪些子系统,涉及哪些相关的类和方法,你须要本身保证顺序(若是功能调用依赖顺序的话)
如同在医院里面,病人须要本身去排队挂号化验,跟每一个流程的工做人员进行协做
如同在工厂里面,须要生产一个桌子,你亲自用机器生产桌子腿,本身使用机器生产桌面...
如同你去其余公司洽谈业务,你单独跟每一个相关业务的人员进行联系沟通
你确定想获得,若是有一个中间人为你代劳
不须要面对林林总总的子系统、部门、人员...
当你须要某种服务时,只须要告诉这个中间人就行了
这个想法就是外观模式
有了facade,你就不须要跟每一个子系统进行单独的交流了
如同在医院里面,对于VIP,有专人代替你挂号.....
如同在工厂里面,有一个控制台机器,你选择产品,控制台下发命令安排其余的机器生产具体产品
如同你去其余公司洽谈业务,有一个接口人负责与你对接,他们那边的事情都经过这我的进行安排
外观模式的意图含义,如同他的名字同样,“建筑物的正面”
面对一个复杂的大楼,当你在正面远远望去,也就只能看到正面
在外观模式中,形容一个庞大的复杂的系统的一个直观的界面
借助于Facade模式
从原来的“客户端须要跟多个子系统进行交互”,转变为“只与Facade进行交互”
将客户端与子系统进行解耦,
下降了耦合性,也下降了使用的复杂度
代码示例
“关好门窗,防火防盗”这句话有没有听过?
回想一下,当你早上准备出门离开家时,你会作什么?
假设你会关水、关灯、关门窗。
咱们建立三个类,水 灯 窗,模拟离开家的场景
package facade;
public class Water {
public void turnOn() {
System.out.println("打开水龙头...");
}
public void turnOff() {
System.out.println("关闭水龙头...");
}
}
package facade;
public class Light {
public void turnOn() {
System.out.println("开灯...");
}
public void turnOff() {
System.out.println("关灯...");
}
}
package facade;
public class Window {
public void open() {
System.out.println("开窗...");
}
public void close() {
System.out.println("关窗...");
}
}
上面的测试代码Test做为客户端程序,能够看得出来,他直接跟Water Light Window三个类的对象进行交互
他须要调用相关的方法
也就是说Test 做为客户端对于“离家”这一系统的内部逻辑是了如指掌的--->须要断水、关灯、关窗
他也清楚每一个类的方法
一方面增长了耦合性,另外一方面将子系统的内部细节暴露出来
优化重构
试想下,若是你家是智能家居,有一个控制台Facade,或者说有一个手机App
他能够控制整个家庭的设备
package facade;
public class Facade {
private Water water = new Water();
private Light light = new Light();
private Window window = new Window();
public void leaveHome(){
water.turnOff();
light.turnOff();
window.close();
}
public void backHome(){
light.turnOn();
window.open();
}
}
经过这个控制台,客户端程序再也不须要了解子系统的内部细节,他也不清楚每一个类到底有哪些方法
全部的交互都是经过Facade来完成的
结构
Facade 外观角色
客户端调用角色,知晓子系统的全部功能与职责
一般,Facade会将全部的请求转发委派到子系统中去,也就是说该角色没有实际的业务、
SubSystem子系统角色
能够同时有一个或者多个子系统
注意 :子系统并非说一个单独的类,而是一个类的集合,这些类根据逻辑功能点被组织在一块儿
子系统并不知道Facade的存在,对于子系统来讲,Facade也就只是一个客户端程序
外观模式的结构比较简单,相似一个“封装”提取的过程
他的
根本原则为迪米特法则,也就是“
不要和陌生人说话”,尽量少的与其余的对象进行交互
经过外观模式,作到了子系统只与外观对象交互
门面类个数
在门面模式中,一般只须要一个门面类,而且这个门面类只有一个实例
换句话说他极可能是一个单例
可是并非说整个系统中只能有一个门面类
门面类的个数要根据系统中子系统的个数以及业务逻辑的状况
总结
当你
须要为一个复杂的子系统提供一个简单的接口时或者但愿子系统可以更加独立时,能够考虑使用外观模式
借助于外观模式,能够实现客户端与子系统的解耦,减小客户端对子系统的依赖性
一旦完成解耦,就意味着子系统有良好的独立性,也能拥有更好的扩展性
由于独立了,就意味着单独的子系统修改不会影响其余系统
并且,
在多层次结构的系统中,可使用Facade模式进行层与层之间的交互,将层与层之间的耦合性下降,使他们仅仅经过facade进行交互
总之一句话,下降了使用子系统的复杂程度,下降了耦合程度,知足迪米特法则----不要和陌生人说话
对客户端屏蔽了子系统的组件
仅仅经过Facade,
大大减小了客户端所须要处理的对象的数目
对于外观模式,
若是是子系统发生变化,Facade则极有可能须要面临修改,这不符合开闭原则
外观模式(门面模式)就如同咱们开篇的图片同样,做为公司前台
接待来访宾客,一切事宜都有她来协调安排组织。
在OOP中,这个“前台”不只是一个子系统的“正面”看到的样子,并且还强调了她的全权负责
她提供全部的业务须要的相关方法,尽管内部调用都是子系统中的方法,她提供简单一致的交流沟通形式
理解了迪米特法则,那么就比较容易理解外观模式
外观模式重点在于提供一个“简化”“封装”后的操做控制台,让你更容易操做整个系统,他几乎不会涉及子系统的内部逻辑
不然,门面对象将与子系统的业务逻辑耦合,增长了耦合度。