一,什么是外观模式
Facade 模式也叫外观模式,是有GoF提出的 23种设计模式中的一种。 Facade模式为一组具有类似功能的类群,比如类库,子系统等等,提供一个一致的简单的界面。这个一致的简单的界面被称作Facade。
在现实生活中,常常存在办事较复杂的例子,如办房产证或注册一家公司,有时要同多个部门联系,这时要是有一个综合部门能解决一切手续问题就好了。
软件设计也是这样,当一个系统的功能越来越强,子系统会越来越多,客户对系统的访问也变得越来越复杂。这时如果系统内部发生改变,客户端也要跟着改变,这违背了“开闭原则”,也违背了“迪米特法则”,所以有必要为多个子系统提供一个统一的接口,从而降低系统的耦合度,这就是外观模式的目标。
二,外观模式的结构
外观模式是一种通过为多个复杂的子系统提供一个一致的接口,而使这些子系统更加容易被访问的模式。该模式对外有一个统一接口,外部应用程序不用关心内部子系统的具体的细节,这样会大大降低应用程序的复杂度,提高了程序的可维护性。
外观模式的角色和职责
- Facade : 为调用方 定义简单的调用接口。
- Clients : 调用者。通过Facade接口调用提供某功能的内部类群。
- Packages: 功能提供者。指提供功能的类群(模块或子系统)。
优点:
- 降低了子系统与客户端之间的耦合度,使得子系统的变化不会影响调用它的客户类。
- 对客户屏蔽了子系统组件,减少了客户处理的对象数目,并使得子系统使用起来更加容易。
- 降低了大型软件系统中的编译依赖性,简化了系统在不同平台之间的移植过程,因为编译一个子系统不会影响其他的子系统,也不会影响外观对象。
确定:
- 不能很好地限制客户使用子系统类。
- 增加新的子系统可能需要修改外观类或客户端的源代码,违背了“开闭原则”。
三,外观模式简单代码实现
Packages: 功能提供者。指提供功能的类群(模块或子系统)
public class SystemA {
public void doSomething(){
System.out.println("实现A");
}
}
public class SystemB {
public void doSomething(){
System.out.println("实现B");
}
}
public class SystemC {
public void doSomething(){
System.out.println("实现C");
}
}
Facade : 为调用方 定义简单的调用接口。
public class Facade {
private SystemA systemA;
private SystemB systemB;
private SystemC systemC;
public Facade() {
systemA = new SystemA();
systemB = new SystemB();
systemC = new SystemC();
}
public void doSomething(){
this.systemA.doSomething();
this.systemB.doSomething();
this.systemC.doSomething();
}
}
测试:
public class Test {
public static void main(String[] args) {
Facade facade =new Facade();
facade.doSomething();
}
}
四:外观模式的应用场景
- 对分层结构系统构建时,使用外观模式定义子系统中每层的入口点可以简化子系统之间的依赖关系。
- 当一个复杂系统的子系统很多时,外观模式可以为系统设计一个简单的接口供外界访问。
- 当客户端与多个子系统之间存在很大的联系时,引入外观模式可将它们分离,从而提高子系统的独立性和可移植性。
五:外观模式的扩展
在外观模式中,当增加或移除子系统时需要修改外观类,这违背了“开闭原则”。如果引入抽象外观类,则在一定程度上解决了该问题。 如图: