Facade Pattern 门面模式是一种比较常用的封装模式,其定义如下:
Provide a unified interface to a set of interfaces in a subsystem. Facade defines a higher-level interface that makes the subsystem easier to use.
要求一个子系统的外部与其内部的通信必须通过一个统一的对象进行,门面模式提供一个高层次的接口,使得子系统更易于使用。
门面模式的角色定义:
1,Facade门面角色
客户端可以调用就只有这个角色的方法,此角色知晓子系统所有功能和责任。
2,Subsystem子系统角色
可以同时有一个或多个子系统,每个子系统都不是一个单独的类,而是一个类的集合。子系统并不知道门面的存在,对于子系统而言,门面仅仅是另一个客户端而言。
通用源码,实在太简单,我都不想写了:
public class ClassA { public void doSomething() { System.out.println("ClassA dosomething..."); } }
public class ClassB { public void doSomething() { System.out.println("ClassB dosomething..."); } }
public class Facade { // 被委托对象 private ClassA a = new ClassA(); private ClassB b = new ClassB(); // 提供给外部访问的方法: public void methodA() { this.a.doSomething(); } public void methodB() { this.b.doSomething(); } }
门面模式的优点:
1,减少系统的相互依赖
2,提高了灵活性
3,提高了安全性:想让你访问子系统的哪些业务就开通哪些逻辑,不在门面上开通的方法,你休息访问到。
门面模式的缺点:
不符合开闭原则,对修改关闭,对扩展开放。看看门面Facade对象,一旦系统投产后发现了一个小小bug,你怎么解决,继承和覆写都无法解决,只能去修改Facade角色的代码,这个风险太大了。
门面模式使用场景:
1,为一个复杂的模块或子系统提供一个供外界访问的接口
2,子系统相对独立 -- 外界对子系统的访问只要黑箱操作即可
3,预防低水平程序员带来的风险扩散
门面模式注意事项:
1,一个子系统可以有多个门面
当门面庞大到不能忍受的程度,比如门面对象超过了200行代码,可以按照功能来拆分
子系统提供不同的路径访问,比如一个门面可以访问所有子系统功能,另一个只能访问受限的几个
2,门面千万不要参与子系统内的业务逻辑
必须确保即使门面不存在,也能靠子系统实现所有功能,也就是说门面对象不能有自己的业务逻辑方法,只能由子系统调用链。
最佳实践:
门面模式是一个很好的封装方法,一个子系统比较复杂时,比如算法或者业务比较复杂,就可以封装出一个或多个门面出来。技术水平比较差的成员,尽量安排独立模块,然后把他写的程序封装到一个门面中去,尽量让别人不用看到这些人的代码,然后对门面的方法进行大量的单元测试,约束代码质量。
本人博客已搬家,新地址为:http://yidao620c.github.io/