外观模式(facade)
简单来说就是提供一个访问子系统的统一入口,这个类中组合其他的子系统类,涉及到的方法统一调用。
日常开发中会经常不经意间使用外观模式,当涉及到两个以上的变量时我们就会习惯性的将其封装成类。
-
解决什么问题
-
当客户端要同时调用许多子系统时,可以将众多子系统组合到同一个类中,统一设计一个简单接口供外界对其他子系统进行调用。
-
如果你的程序需要与包含几十种功能的复杂库整合, 但真正使用的只是其中非常少的功能。可以将其封装在一个类中,在内部对涉及到的对象进行统一初始化,生命周期的管理等,并且挑其中与用户有关的方法整合暴露出来。
-
-
结构图
-
基础版:
-
进阶版(详情见扩展):
-
-
实现代码
//外观类 class Facade { private SubSystem01 obj1 = new SubSystem01(); private SubSystem02 obj2 = new SubSystem02(); private SubSystem03 obj3 = new SubSystem03(); public void method() { obj1.method1(); obj2.method2(); obj3.method3(); } }
//子系统角色1 class SubSystem01 { public void method1() { System.out.println("子系统01的method1()被调用!"); } }
//子系统角色2 class SubSystem02 { public void method2() { System.out.println("子系统02的method2()被调用!"); } }
//子系统角色3 class SubSystem03 { public void method3() { System.out.println("子系统03的method3()被调用!"); } }
public static void main(String[] args) { Facade f = new Facade(); f.method(); }
输出:
-
缺点
-
不能对客户端访问子系统产生限制(相反,运用外观模式的同时也可以调用外观模式所引用的子系统)
-
外观类可能会成为上帝对象
-
当有新的子系统加入时需要手动更改外观类内的代码,违反代码的开闭原则。针对这种情况,有了如下的扩展方案:
-
-
扩展:
引入抽象外观类,当有新业务时新继承一个类来扩展原有功能,避免污染原有的单一外观类(见进阶版的图)。