外观设计模式(Facade Pattern)是为了解决类与类之间的依赖关系的,像spring一样,可以将类和类之间的关系配置到配置文件中,而外观模式就是将他们的关系放在一个Facade类中,降低了类类之间的耦合度。

1、外观模式组成

(1)外观角色(Facade):是模式的核心,他被客户client角色调用,知道各个子系统的功能。同时根据客户角色已有的需求预订了几种功能组合;

(2)子系统角色(Subsystem classes):实现子系统的功能,并处理由Facade对象指派的任务。对子系统而言,facade和client角色是未知的,没有Facade的任何相关信息;即没有指向Facade的实例;

(3)客户角色(client):调用facade角色获得完成相应的功能;

Java设计模式学习篇(八)外观设计模式_java

2、举例

    电脑启动需要启动CPU、磁盘、内存等。我们可以将各部分分为不同的子系统去实现。实现类的关系如图:

Java设计模式学习篇(八)外观设计模式_java_02

假设CPU类、Memory类、Disk类实现如下:

Java设计模式学习篇(八)外观设计模式_java_03

Java设计模式学习篇(八)外观设计模式_java_04

Java设计模式学习篇(八)外观设计模式_java_05

     作为外观设计模式,我们重点要实现的是Computer类,即如何操作其他类(主要持有其他类的引用)。

   实现如下:

Java设计模式学习篇(八)外观设计模式_java_06

测试类如下: 

Java设计模式学习篇(八)外观设计模式_java_07

3 总结:

       外观设计模式解决了类与类之间的依赖关系。这是一个很好的封装方法,一个子系统比较复杂的实话,比如算法或者业务比较复杂,就可以封装出一个或多个子类(Sub System)出来,项目的结构简单,而且扩展性非常好。还有,在一个较大项目中的时候,为了避免人员带来的风险,也可以使用这个模式,技术水平比较差的成员,尽量安排独立的模块(Sub System)。

思考:外观模式比较简单,在什么地方应用呢?

     其实外观模式应用很广泛,比如我们在项目中最底层封装成固定的类,中间层使用这些封装好的类实现进一步封装、拓展。最顶层应用继续使用中间层封装好的类去实现。所以说这种思想在我们周围很常见。

      用户只需要管理好自己这一层的类(如本例中的Computer类),需要扩展功能,也只要在这个类里面添加即可。

 思考2:外观设计模式还能扩展吗?

      每一种设计模式都不是完美的,在实际应用中进行融合。比如,我可以将下面的子类(CPU)设计成接口或抽象类,然后交由不同的子类去实现。在Computer类中,我们可以根据调用的具体子类去实现具体功能,进一步增强了扩展性。可以参考List框架。List是一个接口,下面的ArrayList、LinkedList类实现了List接口。在调用时,可以设计一个类调用ArrayList或LinkedList。