外观模式

54 阅读3分钟

Facade

别名:门面模式

定义

提供一个统一的接口,用来访问子系统中的一群接口。

应用场景

1.如果你需要一个指向复杂子系统的直接接口,且该接口的功能有限,则可以使用外观模式

子系统通常会随着时间的推进变得越来越复杂。由于创建了许多类,其所需的配置和样板代码数量也会许多。

2.如果需要将子系统的组织为多层结构,可以使用外观

创建外观来定义子系统中各层次的入口。你可以要求子系统仅用外观来进行交互,来减少子系统之间的耦合。

实现方法

1.当该接口能让客户端代码独立于众多子系统类,则可以考虑在现有子系统的基础上提供一个更简单的接口。

2.在一个新的外观类中声明并实现该接口。外观应将客户端代码的调用重定向到子系统中的相应对象处。如果客户端代码未对子系统进行初始化,也没有对其后续生命周期进行管理,那么外观必须完成此类工作。

3.必须确保所有客户端代码仅通过外观来与子系统进行交互。此后客户端将不会受到任何由系统代码修改而造成的影响。eg:子系统升级后,你只需改外观的代码即可

优缺点

优点:

可以使代码独立于复杂子系统,简化调用过程

缺点:

外观可能成为程序中所有类都耦合的上帝对象

结构

UML图

classDiagram
Client --> Facade
Facade --> AdditionalFacade
Facade..>Subsystem_more
AdditionalFacade..>Subsystem_more
class Facade{
	-linksToSubsystemObjects
	-optionalAddtionFacade
	+subsystemOperation()
}
class AdditionalFacade{
	...
	+anotherOperation()
}

参与者

1.外观( Facade )提供了一种访问特定子系统功能的便捷方式,其了解如何重定向客户端请求, 知晓如何操作一切活动部件。

2.创建附加外观(Additional Facade)类可以避免多种不相关 的功能污染单一外观, 使其变成又一个复杂结构。 客户端和 其他外观都可使用附加外观。

3.复杂子系统(Complex Subsystem)由数十个不同对象构成。 如果要用这些对象完成有意义的工作, 你必须深入了解子系 统的实现细节, 比如按照正确顺序初始化对象和为其提供正确格式的数据。

子系统类不会意识到外观的存在, 它们在系统内运作并且相 互之间可直接进行交互。

4.客户端(Client)使用外观代替对子系统对象的直接调用。

通用写法

public class Facade {
   private Map<String,Object> linksToSubsystemObjects;
   private AdditionalFacade optionalAdditionalFacade;
​
   public void subsysteamOperation(){
       SubsystemA subsysteamA = new SubsystemA();
       subsysteamA.opera();
       SubsystemZ subsysteamZ = new SubsystemZ();
       subsysteamZ.opera();
  }
}
​
public class AdditionalFacade {
   private Map<String,Object> linksToSubsystemObjects;
   private AdditionalFacade optionalAdditionalFacade;
​
   public void anotherOperation(){
       SubsystemB subsysteamB = new SubsystemB();
       subsysteamB.opera();
       SubsystemZ subsysteamZ = new SubsystemZ();
       subsysteamZ.opera();
  }
}
​
​
public class SubsystemA {
   public void opera(){
       System.out.println("subsystemA Come");
  }
}
public class SubsystemB {
   public void opera(){
       System.out.println("subsystemB Come");
  }
}
public class SubsystemZ {
   public void opera(){
       System.out.println("subsystemZ Come");
  }
}
​
public class Client {
   public static void main(String[] args) {
       Facade facade = new Facade();
       facade.subsysteamOperation();
​
       facade.setOptionalAdditionalFacade(new AdditionalFacade());
​
       facade.getOptionalAdditionalFacade().anotherOperation();
  }
}