【Java设计模式】结构型设计模式-门面模式(八)
门面模式
门面模式(Facade),也叫 “外观模式”:门面模式为子系统中的一组接口提供一个一致的门面(也就是软件的入口),此模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。门面模式通过定义一个一致的接口,用以屏蔽内部子系统的细节,使得调用者只需跟这个接口发生调用,而无需关心这个子系统的内部细节。
门面模式包含三种角色:
- Facade(门面类):为调用者提供统一的调用接口, 门面类知道哪些子系统负责处理请求并完成相关的请求处理,从而将调用者的请求转交给适当子系统对象去完成处理。
- Client (调用者): 门面接口的调用者,也就是使用者。
- SubSystemList(子系统的集合)也就是门面接口实现类中的成员变量:指模块或者子系统,去实际处理 Facade对象指派的任务,他是功能的实际提供者。
案例:我们以烹饪为例,从商品购买食材,到切菜烹饪整个过程演示门面模式。其中Cooker就是门面类,Client类就是调用者类,其他类都属于子系统的集合。
UML类图:
客户端Client类:
/**
* 这里客户端模拟人对象
*/
public class Client {
public static void main(String[] args) {
Cooker cooker = new Cooker();
cooker.cooking();
System.out.println("开始吃碗里做好的食物");
}
}
厨师类Cooker类:
/**
* 模拟厨师对象
*/
public class Cooker {
private Shop shop = new Shop();
private Water water = new Water();
private FoodKnife fk = new FoodKnife();
private IronPan pan = new IronPan();
private Stove stove = new Stove();
private Bowl bowl = new Bowl();
/**
* 烹饪方法
*/
public void cooking() {
//从菜市场将食材买到
Food food = shop.getFood();
//对食材进行清洗
water.wash(food);
//将食材用菜刀进行切加工
fk.cut(food);
//将切好的食材放入铁锅中
pan.makeIn(food);
//将灶台点火并将装有食材的铁锅放上去进行煎炒
stove.fireUpAndPlace(pan, food);
//煎炒完毕放入碗中可以吃了
bowl.makeIn(food);
}
}
Shop商店类:
/**
* 商店类
*/
public class Shop {
/**
* 购买食材方法
*/
public Food getFood() {
System.out.println("从菜市场买到了食材");
return new Food();
}
}
食品Food类:
/**
* 食品类
*/
public class Food {
}
水Water类:
/**
* 水类
*/
public class Water {
/**
* 洗食材方法
*/
public void wash(Food food) {
System.out.println("对食材用水进行清洗。");
}
}
菜刀FoodKnife类:
/**
* 菜刀类
*/
public class FoodKnife {
/**
* 切食材方法
*/
public void cut(Food food) {
System.out.println("用菜刀切食材,使之达到可以直接下锅的状态。");
}
}
铁锅IronPan类:
/**
* 铁锅类
*/
public class IronPan {
/**
* 放入食材
*/
public void makeIn(Food food) {
System.out.println("将切好的食材放入铁锅中");
}
/**
* 炒食材
*/
public void saute(Food food) {
System.out.println("对食材进行煎炒……");
}
}
天然气灶Stove类:
/**
* 天然气灶类
*/
public class Stove {
/**
* 点火并放上铁锅方法
*/
public void fireUpAndPlace(IronPan pan, Food food) {
pan.saute(food);
}
}
碗Bowl类:
/**
* 碗类
*/
public class Bowl {
/**
* 盛东西
*/
public void makeIn(Food food) {
System.out.println("将做好的食材盛入碗中……");
}
}
总结:
- 门面模式对外屏蔽了子系统的细节,因此门面模式降低了客户端对子系统使用的复杂性。
- 门面模式对客户端与子系统的直接耦合关系进行了解耦,让子系统内部的模块更易维护和扩展。
- 通过合理的使用门面模式,可以帮我们更好的划分访问的层次,形成较为合理的层次结构,特别是在分层模块化架构的时候,就应该使用门面模式。
- 在维护一个遗留的大型系统时,可能这个系统已经变得非常难以维护和扩展,此时可以考虑为新系统开发一个Facade 类,来提供遗留系统的比较清晰简单的接口,让新系统与 Facade类交互,提高代码的可复用性。
- 不能过多或者滥用门面模式,使用门面模式好,还是直接调用模块好。要以让系统有层次,利于维护为目的。
- 门面模式将具体实现细节和调用者去调控进行分离,使得调用者对其功能的内部细节实现方式不关心,就遵守了迪米特法则,调用者尽可能少的知道其要实现功能的者的内部实现细节。
转载自:https://juejin.cn/post/7353152184274190390