概述
外观模式(Facade Pattern),属于结构型模式,向客户端提供一个访问系统的接口,该接口隐藏了系统内部复杂的结构。这种模式降低了客户端与系统之间的耦合度,转为外观类与系统间的耦合。
外观模式定义了一个接口,该接口主要为了客户端更加容易调用子系统(多个类),主要为了降低复杂系统访问的复杂度。
该模式下,客户端不需要知道系统内部的复杂结构。
在客户端和应用系统之间加一层,这一层将调用顺序,依赖关系等处理定义好。
实例
以包饺子为例,包饺子需要和面、擀皮、调馅、动手包、下锅,分别对应下面几个类
//和面
public class HuoMian {
public void huo() {
System.out.println("和面。。");
}
}
//擀皮
public class GanPi {
public void gan() {
System.out.println("擀皮。。");
}
}
//调馅
public class TiaoXian {
public void tiao() {
System.out.println("调馅。。");
}
}
//动手包
public class DongShouBao {
public void bao() {
System.out.println("动手包。。");
}
}
//下锅
public class XiaGuo {
public void zhu() {
System.out.println("下锅煮。。");
}
}
客户端测试类
public class ClientTest {
public static void main(String[] args) {
//和面
HuoMian huoMian = new HuoMian();
huoMian.huo();
//擀皮
GanPi ganPi = new GanPi();
ganPi.gan();
//调馅
TiaoXian tiaoXian = new TiaoXian();
tiaoXian.tiao();
//动手包
DongShouBao dongShouBao = new DongShouBao();
dongShouBao.bao();
//下锅煮
XiaGuo xiaGuo = new XiaGuo();
xiaGuo.zhu();
System.out.println("好了,开吃!!");
}
}
输出结果
可以发现,客户端需要逐类调用,若中间出了些许差错,如在调用和面方法之前调用擀皮方法,包饺子这一功能还能正常实现吗?
用外观模式实现
public class BaoJiaoZi {
private HuoMian huoMian;
private GanPi ganPi;
private TiaoXian tiaoXian;
private DongShouBao dongShouBao;
private XiaGuo xiaGuo;
//构造方法
public BaoJiaoZi() {
huoMian = new HuoMian();
ganPi = new GanPi();
tiaoXian = new TiaoXian();
dongShouBao = new DongShouBao();
xiaGuo = new XiaGuo();
}
//包饺子方法
public void bao() {
//和面
huoMian.huo();
//擀皮
ganPi.gan();
//调馅
tiaoXian.tiao();
//动手包
dongShouBao.bao();
//下锅煮
xiaGuo.zhu();
System.out.println("饺子自动做好了!!");
}
}
客户端测试类
public class FacedePatternDemo {
public static void main(String[] args) {
BaoJiaoZi baoJiaoZi = new BaoJiaoZi();
baoJiaoZi.bao();
System.out.println("好了,开吃!!");
}
}
用外观模式的方式就像去饭店点一盘饺子一样,跟服务员说一声,啥都不用管了,坐着等吃就行了:)
从上面的例子可以看到,几个包饺子的步骤类和外观类是聚合关系,客户类现在不需要跟几个步骤类打交道。
这种设计模式的好处是显而易见的,客户端跟子系统松散耦合,子系统的更改对客户端没有直接影响;外观类可根据需要更改算法(如先调馅再和面);增加子系统或替换子系统,对客户端没有直接影响。
总结
优点:减少系统间的相互依赖,提高灵活性和安全性。
缺点:不符合开闭原则,若要改东西很麻烦,继承重写都不合适。
外观模式的本质是封装交互,简化调用。该模式不是给子系统添加新的功能接口,而是为让外部减少与子系统中多个模块的交互,松散耦合,从而让外部能够更简单地使用子系统。