一、外观模式介绍
外观模式(Facade Pattern)也叫过程模式,它属于结构型模式。外观模式通过定义一个一致的接口,用以屏蔽内部子系统的细节,使得调用端只需跟这个接口发生调用,而无需关心这个子系统的内部细节,隐藏了系统的复杂性。
这种模式涉及到一个单一的类,该类提供了客户端请求的简化方法和对现有系统类方法的委托调用。
外观类模式角色:
- 子系统的集合:指模块或者子系统,处理Facade对象指派的任务,它们是功能的实际提供者。
- 外观类(
Facade):为调用端提供统一的调用接口,外观类知道哪些子系统负责处理请求,从而将调用端的请求代理给适当子系统对象。此处我们用一个示例来进行说明:
- 诉求:通过调用各对象方法完成烹饪这一过程动作。
- 传统模式下,我们会创建不同对象,不同方法让客户端进行过程的调用。(但该方式明显会给客户端调用增加使用成本)。
- 解决方案:使用外观模式。
二、外观模式使用
2.1 示例关系:
2.2 代码实现:
- 各子系统对象
/* *
* 蔬菜对象及相关操作步骤。
*/
class Vegetables {
/* *
* 饿汉式创建Vegetables实例。
*/
private Vegetables() {
}
private static final Vegetables INSTANCE = new Vegetables();
public static Vegetables getInstance() {
return INSTANCE;
}
public void wash() {
System.out.println(" 洗菜 ");
}
public void cut() {
System.out.println(" 切菜 ");
}
}
/* *
* 肉对象及相关操作步骤。
*/
class Meat {
/* *
* 饿汉式创建Meat实例。
*/
private Meat() {
}
private static final Meat INSTANCE = new Meat();
public static Meat getInstance() {
return INSTANCE;
}
public void cut() {
System.out.println(" 切肉 ");
}
public void boil() {
System.out.println(" 将肉焯水 ");
}
}
/* *
* 调料对象及相关操作步骤。
*/
class Flavour {
/* *
* 饿汉式创建Flavour实例。
*/
private Flavour() {
}
private static final Flavour INSTANCE = new Flavour();
public static Flavour getInstance() {
return INSTANCE;
}
public void match() {
System.out.println(" 搭配调料 ");
}
public void mix() {
System.out.println(" 放入调料调味 ");
}
}
/* *
* 燃气灶对象及相关操作步骤。
*/
class GasStove {
/* *
* 饿汉式创建GasStove实例。
*/
private GasStove() {
}
private static final GasStove INSTANCE = new GasStove();
public static GasStove getInstance() {
return INSTANCE;
}
public void on() {
System.out.println(" 开火 ");
}
public void cooking() {
System.out.println(" 炒菜中... ");
}
public void off() {
System.out.println(" 关火 ");
}
}
- 外观类
/* *
* 烹饪外观对象。
* 1. 无参构造中调用各对象创建实例方法。
* 2. 根据不同阶段,调用不同对象的操作步骤重新组合到新方法中。
*/
class CuisineFacade {
private final Vegetables vegetables;
private final Meat meat;
private final Flavour flavour;
private final GasStove gasStove;
public CuisineFacade() {
super();
this.vegetables = Vegetables.getInstance();
this.meat = Meat.getInstance();
this.flavour = Flavour.getInstance();
this.gasStove = GasStove.getInstance();
}
public void ready() {
vegetables.wash();
meat.boil();
vegetables.cut();
meat.cut();
flavour.match();
}
public void start() {
gasStove.on();
gasStove.cooking();
flavour.mix();
}
public void end() {
gasStove.off();
}
}
- 客户端调用
public class Client {
public static void main(String[] args) {
CuisineFacade cuisineFacade = new CuisineFacade();
cuisineFacade.ready();
cuisineFacade.start();
cuisineFacade.end();
// 洗菜
// 将肉焯水
// 切菜
// 切肉
// 搭配调料
// 开火
// 炒菜中...
// 放入调料调味
// 关火
}
}
三、外观模式总结
特点:
- 外观模式对外屏蔽了子系统的细节,降低了客户端对于子系统使用的复杂度。
- 客户端和子系统解耦,使得子系统系统内部模块更易维护和拓展。
- 通过合理地使用外观模式,可以帮助我们更好地划分访问层次。
注意事项:
- 不能过多或者不合理使用外观模式。(无论使用外观模式或者直接调用模块,我们都要以系统有层次,利于维护为目的。)
应用场景:
- 维护遗留的大型系统时,可能系统变得难以拓展和维护,此时可以考虑外观模式,通过提供一个简单清晰的接口,让新系统与
Facade类交互,提高复用性。MyBatis中的Configuration类使用到了该模式。
四、结束语
“-------怕什么真理无穷,进一寸有一寸的欢喜。”
微信公众号搜索:饺子泡牛奶。