外观模式外部与一个子系统的通信必须通过一个统一的门面对象进行
1、意图
为子系统提供了一个更高层次、更简单的接口,从而降低了子系统的复杂度和依赖性。这使得子系统更易于使用和管理。对外提供一个统一的接口,用来访问子系统中的一系列接口。外观是一个能为子系统和客户提供简单接口的类。当正确的应用外观时,客户不在直接和子系统中的类交互,而是与外观交互。
外观承担与子系统中类交互的责任。实际上,外观是子系统与客户的接口,这样,外观模式降低了子系统和客户的耦合度。外观对象隔离了客户和子系统对象,从而降低了耦合度。当子系统中的类进行改变时,客户端不会像以前一样受影响。
例如:我们去银行办理银行卡的时候,总是会有一个银行的接待人员来帮助我们办理,因为办理银行卡的步骤相对繁琐一些,需要经过填表、录入信息等等流程才可以完成银行卡的办理。那么光靠用户自己去操作是非常耗时的,而且用户体验也会大大降低,所以银行给我们提供了一个接待员,接待员帮助我们规避了流程中的大部分繁琐操作,从而让我们在办卡的时候感觉到高效和便捷。
2、角色及其职责
- 门面角色:客户端可以调用这个角色的方法。此角色知晓相关的子系统功能和责任。正常情况下,本角色会将所有从客户端发来的请求委派到相应的子系统中去
- 子系统角色:可以同时有一个或者多个子系统。每一个子系统都不是一个单独的类,而是一个类的集合。每一个子系统都可以被客户端直接调用,或者被门面角色调用。子系统并不知道门面的存在,对于子系统而言,门面仅仅是另一个客户端而已
银行办理代码:
package com.ag.structure;
public class FaceMode {
public static void main(String[] args) {
OperationSystem operationSystem = new OperationSystem();
operationSystem.startingWork();
}
}
interface Component {
public void work();
}
class InputInfo implements Component{
public void work() {
System.out.println("现在在录入用户基本信息~");
}
}
class InputPassword implements Component{
public void work() {
System.out.println("现在在录入银行卡密码~");
}
}
class MakingCard implements Component{
public void work() {
System.out.println("信息填写完毕,现在开始制做银行卡~");
}
}
//门面类
class OperationSystem {
private Component inputInfo;
private Component inputPassword;
private Component makingCard;
public OperationSystem() {
this.inputInfo = new InputInfo();
this.inputPassword = new InputPassword();
this.makingCard = new MakingCard();
}
public void startingWork(){
System.out.println("开始办理银行卡~");
inputInfo.work();
inputPassword.work();
makingCard.work();
}
}
3、使用范围
- 不需要使用一个复杂系统的所有功能,而且可以创建一个新的类,包含访问系统的所有规则
- 希望封装或者隐藏原系统
- 希望使用原系统的功能,而且还希望增加一些新的功能
- 编写新类的成本小于所有人学会使用或者未来维护原系统上所需的成本
4、优缺点
优点:装饰器模式可以减少系统依赖(指的是对外的系统依赖);提高灵活性;提高安全性
缺点:把很多东西糅合到一起,可能会带来未知的风险;增加新的子系统可能需要修改外观类或者客户端的源代码,违反了“开闭原则”