1.适配器模式 2.桥接模式 3.组合模式 4.代理模式 5.装饰模式 6.外观模式 7.享元模式
由于学习难度较大 并且相对用途较少 本章不会讲解享元模式
接下来针对以上6种设计模式进行单独讲解
6 外观模式
6.1 定义
外部与一个子系统的通信通过一个统一的外观角色进行,为子系统中的一组接口提供一个一致的入口。外观模式定义了一个高层接口,这个接口使得子系统更加容易使用。外观模式又称为门面模式,它是一种对象结构型模式。
例如:在家喝茶需要自己泡茶,那么便需要知道要泡的茶的种类,要准备茶具,要准备开水等。而去茶馆喝茶只需要告诉服务员说要喝什么茶便可,具体泡茶步骤都是服务员进行。顾客只需与服务员交互,而具体的复杂操作被服务员屏蔽,此例中服务员便类似于外观角色。
外观角色为多个业务类的调用提供了统一的入口,简化了客户端与服务端的交互耦合。
6.2 UML图
从上面UML图中可以看出
Facade为外观角色类,在客户端可以调用这个角色的方法,在外观角色中可以知道相关的(一个或者多个)子系统的功能和责任。在正常情况下,它将所有从客户端发来的请求委派到相应的子系统中去,传递给相应的子系统对象处理。
SubSystem为子系统角色类,在软件系统中可以有一个或者多个子系统角色。每个子系统可以不是一个单独的类,而是一个类的集合,它实现子系统的功能。每个子系统都可以被客户端直接调用,或者被外观角色调用,它处理由外观类传过来的请求。子系统并不知道外观的存在,对于子系统而言,外观角色仅仅是另外一个客户端而已。
6.3 代码实现
// SubSystemA.java
public class SubSystemA {
public void operationA() {
System.out.println("SubSystemA operation");
}
}
// SubSystemB.java
public class SubSystemB {
public void operationB() {
System.out.println("SubSystemB operation");
}
}
// Facade.java
public class Facade {
private SubSystemA subSystemA;
private SubSystemB subSystemB;
public Facade() {
subSystemA = new SubSystemA();
subSystemB = new SubSystemB();
}
public void clientOperation() {
subSystemA.operationA();
subSystemB.operationB();
}
}
// Client.java
public class Client {
public static void main(String[] args) {
Facade facade = new Facade();
facade.clientOperation();
}
}
6.4 扩展
其实相对而言,外观模式并没有相对固定的UML图示例,更多的是一种设计思想,让客户端和服务端的耦合尽可能的小,这有利于降低系统原有交互的复杂性,如果没有外观模式,那么客户端将要面临一个请求和服务端多个类进行交互及客户端需要编排该服务流程。
举例说明:客户端需要实现功能A,此功能依赖B类,C类,D类的共同作用实现。如果没有外观模式那么客户端需要先调用B,再调用C最后调用D,抽象出外观(Facade)之后客户端只需要和外观Facade交互,具体调用逻辑由Facade编排。