外观模式 门面模式 Facade 结构型 设计模式(十三)
外观模式(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来完成的