本文首发于 http://www.YoungZY.com/
意图
- 为一组子系统的接口提供一个统一的接口。门面模式定义了一个更高层次的接口使得子系统更容易使用
- 用一个简单的接口封装复杂的子系统
问题
对于整体功能比较复杂的子系统,有一部分客户群体需要一个更简洁的接口。
讨论
门面模式讨论的是将一个复杂的子系统封装在一个接口对象里。这降低了子系统和用户之间的耦合性,也减少了使用子系统的学习曲线。另一方面,如果”门面”是子系统的唯一访问点,它会限制高级用户可能需要的一些特性和灵活性。
门面对象应该是一个相当简单的支持或促进的角色,而不是一个全知全能的先知或者神。
结构
门面模式有中拨开迷雾的功能,它用一个封装类”驯服”了软件系统中多变的、难以捉摸的东西。
SubsystemOne
和 SubsystemThree
不和核心组件 SubsystemTwo
直接交互,而是通过门面类 SubsystemTwoWrapper
,即更高层次的抽象类。
举例
消费者在从目录订购时会遇到门面模式。消费者拨打电话和客服代表交流。这个客服代表就充当了门面模式,提供了一种途径去告知订单执行部门,结算部门和运输部门。
核查清单(也可以理解为应用步骤)
- 为子系统或组件找到一个更简单的、统一的接口
- 设计一个包装类去封装子系统
- 门面类(或封装类)记录了组件间的复杂关系和交互,再将其委托给合适的方法
- 用户只使用门面类(只与门面类耦合)
- 思考更多的门面类能否带来更多的价值
经验法则
- 门面类通常是单例的,因为只需要一个门面对象
问: 也就是说适配器模式和门面模式的区别在于:适配器模式封装了一个类,而门面模式封装了多个类?
答: 不!记住,适配器模式是将一个或多个接口转变为一个客户想要的接口。前面的适配器模式的示例适配了一个类,实际工作中你可能需要适配多个类。而门面模式是给一个非常复杂的接口类提供一个更简便的接口。他们的区别不是类的数量,而是他们的目的。
(译者注:详细的代码实例请移步 GitHub )
加入讨论