定义:为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口使得这个子系统更加容易使用。
通过将子系统中一系列的接口进行组合形成一个更高层的接口,这样客户端在调用的时候不必将子系统的接口逐一调用,而是直接调用组合后的高层接口,降低了客户端与子系统之间的耦合度,我们来看下外观模式的结构类图
可以看出,以上主要有四种类,分别是外观接口和外观接口的实现类,还有子系统接口和子系统的实现类。我们来看下具体的代码实现
外观接口
public interface Facade { /** * 组合方法A */ void methodA(); /** * 组合方法B */ void methodB(); }
外观接口的实现类
public class FacadeImpl implements Facade { private SubSystemOne subSystemOne; private SubSystemTwo subSystemTwo; private SubSystemThree subSystemThree; private SubSystemFour subSystemFour; public FacadeImpl() { this.subSystemOne = new SubSystemOneImpl(); this.subSystemTwo = new SubSystemTwoImpl(); this.subSystemThree = new SubSystemThreeImpl(); this.subSystemFour = new SubSystemFourImpl(); } @Override public void methodA() { System.out.println("方法组A"); subSystemOne.methodOne(); subSystemThree.methodThree(); subSystemFour.methodFour(); } @Override public void methodB() { System.out.println("方法组B"); subSystemOne.methodOne(); subSystemTwo.methodTwo(); subSystemThree.methodThree(); } }
子系统的四个接口
public interface SubSystemOne { /** * 方法1 */ void methodOne(); }
public interface SubSystemTwo { /** * 方法2 */ void methodTwo(); }
public interface SubSystemThree { /** * 方法3 */ void methodThree(); }
public interface SubSystemFour { /** * 方法4 */ void methodFour(); }
四个子系统的实现类
public class SubSystemOneImpl implements SubSystemOne { @Override public void methodOne() { System.out.println("子系统方法1"); } }
public class SubSystemTwoImpl implements SubSystemTwo { @Override public void methodTwo() { System.out.println("子系统方法2"); } }
public class SubSystemThreeImpl implements SubSystemThree { @Override public void methodThree() { System.out.println("子系统方法3"); } }
public class SubSystemFourImpl implements SubSystemFour { @Override public void methodFour() { System.out.println("子系统方法4"); } }
客户端的调用和输出结果
Facade facade = new FacadeImpl(); facade.methodA(); System.out.println("-------------"); facade.methodB();
以上就是整个功能是实现代码,可以通过点击以下链接获取代码和类图
从上面的代码可以看出不管是外观类还是子系统都提供了一个接口,使其依赖于抽象,不过这在我们日常的开发中可以不需要这些接口,因为这不仅会导致文件数量增加,而且当我们需要增加一个方法的时候也要增加一个相对应的接口,这样将会导致整个系统变得复杂,影响开发效率。
外观接口中并不一定都像以上例子中,都是有子系统中的多个行为的组合,可以只是通过外观接口暴露子系统中一个单一的功能,也可以添加一些额外的行为,就比如我们经常用到的servcie层的接口,可以是有多个dao方法组合而成,也可以只是单个方法,当然也能在其中编写额外的业务代码
在实际的开发中外观接口往往并不只有一个,若需要暴露的组合功能过多时,就需要将外观接口拆分成多个,形成一个外观层,我们经常用到的service层其实就是一个外观层
那我们在日常的开发中在什么时候需要用到外观模式呢?
首先在开发的初期,我们经常将程序分为controller层、service层和dao层,在这些层与层之前我们可以加入一个外观接口甚至一个外观层,来降低层与层之间的耦合,也方便了各层之间的调用;然后是在开发阶段的时候,子系统会因为不断重构,和使用其他的设计模式,使得产生了许多很小的类,导致客户端在调用的时候难度增大,我们就能通过一个外观接口来解决这一问题;还有就是在维护一个大型系统的时候,有可能我们已经很难对系统中已有的功能进行修改,但是我们又需要里面的功能,就能通过创建一个外观接口来对已有的功能进行调用和组合,这样我们客户端就只需要调用这个非常简单的外观接口就可以了