门面模式的定义
定义: 要求一个子系统的外部与其内部的通信必须通过一个统一的对象进行. 门面模式提供一个高层次的接口, 使得子系统更易于使用.
通俗的说, 就是设计一个类,专门用于对外服务的, 门面对象是外界访问子系统内部的唯一通道
其类图如下:
其中两个角色如下:
- Facade 门面角色: 客户端可以调用这个角色的方法. 此角色知晓子系统的所有功能和责任. 一般情况下, 本角色会将所有从客户端发来的请求委派到相应的子系统去, 也就是说该角色没有实际的业务逻辑, 只是一个委托类
- Subsystem 子系统角色: 可以同时有一个或多个子系统. 每一个子系统都不是一个单独的类, 而是一个类的集合.子系统并不知道门面的存在. 对于子系统而言, 门面仅仅是另外一个客户端而已
子系统代码如下:
门面对象代码:
门面模式的应用
门面模式的优点:
- 减少系统的相互依赖. 如果不使用门面模式, 外界访问直接深入到子系统内部, 相互之间是一种强耦合关系, 这样的强依赖是系统设计所不能接受的. 门面模式的出项很好的解决了这个问题, 所有的依赖都是对门面对象的依赖, 与子系统无关.
- 提高了灵活性. 依赖减少了, 灵活性自然提高了.
- 提高安全性. 想让你访问子系统的哪些业务就开通那些逻辑, 不在门面上开通的方法, 休想访问到
门面模式的缺点:
门面模式最大的缺点就是不符合开闭原则, 对修改关闭, 对扩展开放. 一旦在系统投产后发现有一个小错误, 怎么解决? 完全最从开闭原则,根本没办法解决. 唯一能做的一件事就是修改门面对象的代码, 这个风向相当大.
门面模式的使用场景:
- 为一个复杂的模块或子系统提供一个供外界访问的接口
- 子系统相对独立--外界对子系统的访问只要黑箱操作即可.
- 预防低水平人员带来的风险扩散.
门面模式的注意事项
1.一个子系统可以有多个门面
- 门面已经庞大到不能忍受的重读. 当一个门面对象过于庞大, 虽然都是非常简单的委托操作, 也建议拆分成多个门面,否则会给以后的维护和扩展带来不必要的麻烦. 按照功能拆分是一个非常好的原则, 比如一个数据库操作的门面可以拆分为增删改查等
- 子系统可以提供不同访问路径, 当有两个不同的高层模块来访问子系统, 模块二属于受限访问对象, 只能访问methodB 方法, 如何处理呢?
增加的门面非常简单, 委托给已经存在的门面对象来处理. 这样可以尽量保持相同的代码只编写一遍, 避免以后到处修改相似代码的悲剧.
2.门面不参与子系统内的业务逻辑
门面对象中不要出现具体的业务逻辑代码, 否则就会产生一个倒依赖的问题, 在门面模式中, 门面角色应该是稳定的, 它不应该经常变化, 一个系统一旦投入运行他就不应该被改变, 它是一个系统对外的接口, 变来变去还怎么保证其他模块的稳定运行呢?
如果一定要出现业务处理, 应该建立一个封装类, 封装完毕后提供给门面对象使用.
门面模式是一个很好的封装方法, 一个子系统比较复杂时, 比如算法或者业务比较复杂, 就可以封装出一个或多个门面出来, 项目的接口简单, 而且扩展性非常好. 还有, 对于一个较大的项目, 为了避免人员带来的风险, 也可以使用门面模式.