为一组接口提供一个一致的界面,Facade模式定义了一个高层的接口,这个接口使得这个子系统更加易用。
Facade:定义子系统多个模块对外的高层接口,通常调用多个模块,从而把客户的请求委派给适当的子系统对象。
模块:接受Facade的委派,真正实现具体功能,各个模块之间可能有交互。
注意:Facade知道各个模块,但是各个模块不应该知道Facade对象;Facade的目的是实现客户端和子系统的松散组合,不是实现新的功能;Facade屏蔽了客户端和各个子系统的联系,客户端不需要知道子系统的实现细节。
比如,一个代码生成工具分为:控制层生成模块,逻辑层生成模块,数据层生成模块,配置管理模块。
配置管理模块:
/**
* 示意配置数据的model
*
*/
public class ConfigModel {
/**
* 是否需要生成表现层,默认是true
*/
private boolean needGenerateController = true;
/**
* 是否需要生成逻辑层,默认是true
*/
private boolean needGenerateBusiness = true;
/**
* 是否需要生成数据层,默认是true
*/
private boolean needGenerateDao = true;
public boolean isNeedGenerateController() {
return needGenerateController;
}
public void setNeedGenerateController(boolean needGenerateController) {
this.needGenerateController = needGenerateController;
}
public boolean isNeedGenerateBusiness() {
return needGenerateBusiness;
}
public void setNeedGenerateBusiness(boolean needGenerateBusiness) {
this.needGenerateBusiness = needGenerateBusiness;
}
public boolean isNeedGenerateDao() {
return needGenerateDao;
}
public void setNeedGenerateDao(boolean needGenerateDao) {
this.needGenerateDao = needGenerateDao;
}
}
/**
* 示意配置管理类
*
*/
public class ConfigManager {
private ConfigManager() {};
private volatile static ConfigManager manager = null;
private volatile static ConfigModel cModel;
public static ConfigManager getInstance() {
if(manager == null) {
synchronized (ConfigManager.class) {
if(manager == null) {
manager = new ConfigManager();
cModel = new ConfigModel();
}
}
}
return manager;
}
public ConfigModel getConfigData() {
return cModel;
}
}
数据层生成模块:
/**
* 示意数据层生成模块
*
*/
public class Dao {
public void generate() {
//读取配置信息
ConfigModel cModel = ConfigManager.getInstance().getConfigData();
if(cModel.isNeedGenerateDao()) {
System.out.println("生成数据层代码");
}
}
}
逻辑层生成模块:
/**
* 示意逻辑层生成模块
*
*/
public class Business {
public void generate() {
//读取配置信息
ConfigModel cModel = ConfigManager.getInstance().getConfigData();
if(cModel.isNeedGenerateBusiness()) {
System.out.println("生成逻辑层代码");
}
}
}
控制层生成模块:
/**
* 示意控制层生成模块
*
*/
public class Controller {
public void generate() {
//读取配置信息
ConfigModel cModel = ConfigManager.getInstance().getConfigData();
if(cModel.isNeedGenerateController()) {
System.out.println("生成控制层代码");
}
}
}
以上是各个生成模块,如果不使用Facade模式的话,客户端代码如下:
public class Client {
public static void main(String[] args) {
new Dao().generate();
new Business().generate();
new Controller().generate();
}
}
以上的客户端代码存在的问题是:客户端代码和各个模块的联系紧密,客户端必须了解各个模块才能正确使用。
下面我们看一下使用使用Facade模式后,客户端代码的变化。
外观对象:
public class Facade {
private Facade() {};
public static void generate() {
new Dao().generate();
new Business().generate();
new Controller().generate();
}
}
客户端代码:
public class Client {
public static void main(String[] args) {
Facade.generate();
}
}
优缺点:
1.松散耦合
2.简单易用
3.更好的划分访问层次
4.过多的或者不合理的Facade容易使人迷惑
何时选用:
1.为一个复杂(客户端使用复杂)的多子系统,提供一个简单的接口
2.使客户端和抽象类的实现部分实现松散耦合
3.构建多层次的系统