外观模式学习笔记
在软件开发中,有时候为了完成一项很负责的功能,客户端需要和很多个业务类进行交互,这些业务类通常以一个整体的方式出现,那么这时候就可以引入一个外观类来充当客户端和子系统之间的交互传递者,客户端只需要和外观类交互,就好像外观类是整个子系统对外的一个代理。
外观模式结构图如下所示:
外观模式中,一个子系统的外部与其内部的通信通过一个统一的外观类进行,外观类将客户类与子系统的内部复杂性分隔开,使得客户端只需要与外观角色打交道,而不需要与子系统内部的很多打交道。
定义:外观模式为子系统中的一组接口提供一个统一的入口。外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。它是一种对象结构型模式
而在上面的结构图中主要包含如下两种角色:
- 外观角色 客户端主要就是和外观角色进行沟通的,外观角色知道所有的子系统的功能和责任,他能够将客户端发出的请求分配到相应的子系统当中。
- 子系统角色 子系统就是功能的真正实现的地方,客户端可以直接调用子系统角色,也可以由外观角色调用。
代码如下:
class SubSystemA {
public void MethodA(){ };
}
class SubSystemB {
public void MethodB(){ };
}
class SubSystemC {
public void MethodC(){ };
}
class Facade {
private SubSystemA objA = new SubSystemA();
private SubSystemB objB = new SubSystemB();
private SubSystemC objC = new SubSystemC();
public void method() {
objA.methodA();
objB.methodB();
objC.methodC();
}
}
class Client {
public static void main(String args[]) {
Facade facade = new Facade();
facade.method();
}
}
另外如果系统需要增加新的子系统并且对于业务逻辑等有新的变更的话,那么这时候就需要修改外观模式的代码,这违背了“开闭原则”。因此我们可以设计一个抽象外观类,客户端主要是和抽象外观类打交道。通过创建一个新的外观类来实现新的需求变更,客户端在运行的时候再去确认真正的外观类,执行相应的方法。
interface abstractFacade {
public void method();
}
class Facade implements abstraceFacade {
public void method() {
/*TODO*/
}
}
class newFacade implememts abstraceFacade {
public void method() {
/*TODO*/
}
}
class client {
public static void main(String args[]) {
//abstractFacade af = new Facade();
//abstractFacade af = new newFacade();
af.method();
}
}
外观模式通过引入一个外观类,将客户端类和众多负责业务实现的子系统类隔离开来。如果子系统有变化的话也不会影响到客户端类,只需要调整外观类即可。不能很好的限制客户端类访问子系统类,引入外观类只是提供一个简单的途径给客户端类使用子系统,客户端仍然可以直接调用子系统的。
对于访问一系列的复杂的子系统的话提供一个访问接口的情况,可以使用外观模式。而在层次结构设计中,对于每一层的功能实现,也可以设计成外观模式,相邻层次直接调用外观类即可。