facade [fəˈsɑːd] (建筑物的)正面,立面;(虚假的)表面,外表
外观模式即模块对外部的可视化特征,用于简化客户端操作的一种模式
举个例子:假设小明完全不懂车但是想组装一台汽车,他需要找发动机店的老板买发动机,另一家店买变速箱,还有轮胎店买轮胎等等。。。虽然这些店都在一个专业的商区中,可问题是小明是个外行人自己不懂车,这时候如果找一个懂组装车的人帮他做,他付给人家钱,这种属于代理模式;如果这个商区为了方便大家组装车,在门口设立了一个一站式组装车服务中心,那这个服务中心就相当于本商区对组装车客户提供的方便客户定制的服务,即外观模式。
下面我们用一个具体的例子来说明:做web项目的人员经常需要用到代码生成工具,用来生成Controller、service、dao等代码。我们下面来写一个生成这些代码的jar包供给客户使用
public class ControllerGenerator {
public void generator(){
System.out.println("生成Controller代码");
}
}
public class ServiceGenerator {
public void generator(){
System.out.println("生成Service代码");
}
}
public class DaoGenerator {
public void generator(){
System.out.println("生成Dao代码");
}
}
此时客户如果想使用,可以像下面这样
public class Test {
public static void main(String[] args) {
//生成controller代码
ControllerGenerator controllerGenerator = new ControllerGenerator();
controllerGenerator.generator();
//生成service
ServiceGenerator serviceGenerator = new ServiceGenerator();
serviceGenerator.generator();
//生成dao
DaoGenerator daoGenerator = new DaoGenerator();
daoGenerator.generator();
}
}
这是在客户熟悉你提供的工具类时,可以这样使用,如果客户不熟悉你的工具类不会知道你里面哪个类是用来生成controller的、哪个类是用来生成service的,同事客户又希望快速上手不用花太多时间研究你的工具源码和复杂的文档,怎么办呢?
因为大多数web项目都需要生成这三种类,我们可以提供给用户一个外观类,用来简单快速使用我们的工具。
public class Generator {
public static void generat(){
//生成controller代码
ControllerGenerator controllerGenerator = new ControllerGenerator();
controllerGenerator.generator();
//生成service
ServiceGenerator serviceGenerator = new ServiceGenerator();
serviceGenerator.generator();
//生成dao
DaoGenerator daoGenerator = new DaoGenerator();
daoGenerator.generator();
}
}
此时用户可以不必分别用三个类去生成相应的代码,使用我们提供的外观类会方便和简洁很多。
public class Test {
public static void main(String[] args) {
Generator.generat();
}
}
有的人会问这样做和之前有什么区别呢?不就是吧之前客户端的代码放到了工具类Generator里吗?
没错,确实是这样的。但是他们有质的区别,一个是在客户端一个是在工具类,集成到工具类客户不用再学习复杂的使用情况这也是一种解耦的表现方式。
外观模式的目的不是给子系统添加新的功能,而是为了让外部减少与子系统内多个模块的交互,松散耦合,从而让外部更简单的使用子系统。
注意:外观模式只是提供了更加方便的使用内部子系统的功能,如果用户不想使用封装好的功能,也可以不使用外观类,比如用户只想生成dao的类,则可以会接调用DaoGenerator,用户可以自由组合和使用代码生成工具内部的子模块。
通常外观类会被声明为单例或者声明外观类的方法为static。
当然外观类也可以抽象出接口,然后用简单工厂模式去包装。
外观模式的本质:封装交互,简化调用。