( 十三 )、设计模式 之 外观模式/门面模式(Facade)
( 十三 )、设计模式 之 外观模式/门面模式(Facade)
1、简介
定义:外观模式又称为门面模式,属于结构型模式。外观模式(FacadePattern)隐藏系统内部的复杂性,并向客户端(调用方)提供一个可以访问系统的统一接口。让客户端无需知道系统内部相关的子接口和功能,简化了客户端的使用。
主要解决:降低访问复杂系统的内部子系统时的复杂度,简化客户端之间的接口。
何时使用: 1、客户端不需要知道系统内部的复杂联系,整个系统只需提供一个"接待员"即可。 2、定义系统的入口
优点: 1、减少系统相互依赖。 2、提高灵活性。 3、提高了安全性。
缺点:不符合开闭原则,如果要改东西很麻烦,继承重写都不合适。
2、外观模式的结构说明
- 门面角色(Facade):被客户端角色调用。它熟悉子系统的功能,内部根据客户端角色的需求定制相关功能的组合。
- 子系统角色(Subsystem):实现了子系统内部一系列的逻辑,分成一个个小的功能。
- 客户端角色(Client):这是使用门面模式的外部请求者,它通过门面角色来访问子系统,以获取所需的功能。
3、案例介绍
比如去饭店吃饭,一般的流程如下:点餐、炒菜、上菜、收/付钱。
其实这里的饭店就可以看作是一个门面角色,饭店内不同的角色:如老板、收银员、服务员、厨师等,可以看作是饭店这个门面内的子系统角色,不同的角色职责是不同的,服务员(Waiter)负责帮客人点餐、上菜,厨师炒菜(Cook),收银员负责收钱(Cashier),但是对于客人而言,吃饭是重点,通常不会关注是谁做的、谁端上来的。
4、实现
/**
* @Author dw
* @ClassName Waiter
* @Description 服务员--子系统角色(Subsystem)
* @Date 2023/12/15 17:34
* @Version 1.0
*/
public class Waiter {
public void orderFood() {
System.out.println("->帮客人点菜");
}
public void serveDishes() {
System.out.println("->给客人上菜");
}
}
/**
* @Author dw
* @ClassName Cook
* @Description 厨师--子系统角色(Subsystem)
* @Date 2023/12/15 17:57
* @Version 1.0
*/
public class Cook {
public void cooking() {
System.out.println("->炒菜");
}
}
/**
* @Author dw
* @ClassName Cashier
* @Description 收银员--子系统角色(Subsystem)
* @Date 2023/12/15 17:59
* @Version 1.0
*/
public class Cashier {
public void collectMoney() {
System.out.println("->收钱");
}
}
/**
* @Author dw
* @ClassName Restaurant
* @Description 饭店--相当于门面角色(Facade)
* @Date 2023/12/15 17:33
* @Version 1.0
*/
public class Restaurant {
/**
* 服务员- 这里方便演示直接new了一个, 实际情况可能需要外面传入
*/
private final Waiter waiter = new Waiter();
/**
* 厨师
*/
private final Cook cook = new Cook();
/**
* 收银员
*/
private final Cashier cashier = new Cashier();
/**
* 对外提供统一的吃饭的接口, 客户端不需要关心内部的实现步骤
*/
public void eat() {
// 点餐
waiter.orderFood();
// 上菜
waiter.serveDishes();
// 炒菜
cook.cooking();
// 收银
cashier.collectMoney();
}
}
/**
* @Author dw
* @ClassName Client
* @Description 客户端角色(Client)
* @Date 2023/12/15 18:19
* @Version 1.0
*/
public class Client {
public static void main(String[] args) {
// 创建门面对象
Restaurant restaurant = new Restaurant();
// 调用门面对象的方法,吃饭
restaurant.eat();
}
}