前言
目前正在出一个设计模式专题系列教程, 篇幅会较多, 喜欢的话,给个关注❤️ ~
本节给大家讲一下设计模式中的外观模式,并结合实际业务场景给大家讲解如何使用~
本专题的所有案例代码主要以Java语言为主, 好了, 废话不多说直接开整吧~
外观模式
外观模式(Facade Pattern)是一种结构型设计模式,它为复杂的子系统提供一个简单的接口,使得客户端能够更方便地访问系统的各个功能。外观模式提供了一个高层次的接口,使得客户端与子系统的交互变得更加简单,同时也避免了客户端直接与子系统交互所带来的复杂性。
在外观模式中,我们需要定义一个外观(Facade)类,这个类提供了一个简单的接口,客户端通过这个接口访问系统。外观类隐藏了子系统的复杂性,它把客户端与子系统解耦,使得客户端可以更容易地使用系统的功能。
下面我们通过一个简单的例子来说明外观模式的使用。
假设我们正在开发一个电商平台,该平台有多个服务,包括用户服务、订单服务、库存服务等。每个服务都有自己的接口和实现,客户端需要分别调用这些接口才能完成一个订单的流程。这个过程比较复杂,而且客户端需要了解每个服务的接口和实现,这给客户端带来了很大的负担。
为了简化客户端的代码,我们可以定义一个外观类来封装这些服务的接口。客户端只需要调用外观类的接口就可以完成整个订单流程,而无需了解每个服务的接口和实现。下面是Java代码示例:
// 子系统-用户服务
class UserService {
public void addUser() {
System.out.println("添加用户");
}
}
// 子系统-订单服务
class OrderService {
public void addOrder() {
System.out.println("添加订单");
}
}
// 子系统-库存服务
class InventoryService {
public void deductStock() {
System.out.println("扣减库存");
}
}
// 外观类-订单服务外观
class OrderFacade {
private UserService userService;
private OrderService orderService;
private InventoryService inventoryService;
public OrderFacade() {
userService = new UserService();
orderService = new OrderService();
inventoryService = new InventoryService();
}
// 订单流程
public void order() {
userService.addUser();
orderService.addOrder();
inventoryService.deductStock();
}
}
// 客户端代码
public class Client {
public static void main(String[] args) {
OrderFacade orderFacade = new OrderFacade();
orderFacade.order();
}
}
在上面的代码中,我们定义了三个子系统类:UserService、OrderService和InventoryService,它们分别负责添加用户、添加订单和扣减库存的功能。我们还定义了一个外观类OrderFacade,它封装了这些服务的接口,提供了一个order方法,该方法完成了整个订单流程。最后,我们在客户端代码中创建
最佳实践
假设我们要为电商平台开发一个订单管理系统,该系统需要完成以下几个任务:
- 验证订单信息是否合法。
- 处理订单支付。
- 发送订单信息给物流公司。
首先我们定义一个外观类 OrderFacade,该类对外提供了一个 createOrder 方法,用于创建订单:
public class OrderFacade {
private OrderValidator orderValidator;
private OrderPayment orderPayment;
private LogisticsService logisticsService;
public OrderFacade() {
orderValidator = new OrderValidator();
orderPayment = new OrderPayment();
logisticsService = new LogisticsService();
}
public void createOrder(Order order) {
if (orderValidator.validate(order)) {
orderPayment.pay(order);
logisticsService.ship(order);
} else {
System.out.println("订单验证失败!");
}
}
}
上面的代码中,OrderFacade 对象包含了 OrderValidator、OrderPayment 和 LogisticsService 三个对象,通过调用它们的方法完成订单管理的任务。createOrder 方法接收一个 Order 对象作为参数,先调用 OrderValidator 对象的 validate 方法进行订单验证,如果验证通过则调用OrderPayment对象的pay 方法进行订单支付,最后调用 LogisticsService 对象的 ship 方法发送订单信息给物流公司。如果订单验证失败,则输出一条提示信息。
接下来定义一个 Order 类,表示一个订单:
public class Order {
private String orderId;
private String userId;
private double amount;
public Order(String orderId, String userId, double amount) {
this.orderId = orderId;
this.userId = userId;
this.amount = amount;
}
public String getOrderId() {
return orderId;
}
public String getUserId() {
return userId;
}
public double getAmount() {
return amount;
}
}
然后定义一个 OrderValidator 类,用于验证订单信息是否合法:
public class OrderValidator {
public boolean validate(Order order) {
System.out.println("开始验证订单信息...");
// 假设验证通过
System.out.println("订单验证通过!");
return true;
}
}
接着定义一个 OrderPayment 类,用于处理订单支付:
public class OrderPayment {
public void pay(Order order) {
System.out.println("开始处理订单支付...");
//
}
}
接着定义一个LogisticsService:
public class LogisticsService {
public void ship(Order order) {
System.out.println("SHIP >>>>> " + order.getOrderId());
}
}
最后调用服务
public class FacadeDemo {
public static void main(String[] args) {
OrderFacade facade = new OrderFacade();
facade.createOrder(new Order("xx131423124312331", "1", 96.00));
// 开始验证订单信息...
// 订单验证通过!
// 开始处理订单支付...
// SHIP >>>>> xx131423124312331
}
}
外观模式的优点包括:
- 简化客户端代码:客户端只需要调用外观类的方法即可完成一系列操作,不需要了解内部子系统的实现细节,降低了客户端的复杂度。
- 隐藏实现细节:外观类将子系统的实现细节封装起来,对客户端来说是透明的,这样就能有效地降低客户端与子系统之间的耦合度,实现了解耦。
- 提高系统可维护性:当系统的功能需求发生变化时,只需要修改外观类的方法即可,不需要修改子系统的源代码,这样就降低了系统的维护成本。
结束语
设计模式其实并不难,大家在学习的时候一定要在理解的基础上去写代码,不要去背代码。下节给大家讲享元模式~
本着把自己知道的都告诉大家,如果本文对您有所帮助,点赞+关注鼓励一下呗~
相关文章
- 一起来学设计模式之认识设计模式
- 一起来学设计模式之单例模式
- 一起来学设计模式之工厂模式
- 一起来学设计模式之建造者模式
- 一起来学设计模式之原型模式
- 一起来学设计模式之适配器模式
- 一起来学设计模式之桥接模式
- 一起来学设计模式之组合模式
- 一起来学设计模式之装饰器模式
项目源码(源码已更新 欢迎star⭐️)
Kafka 专题学习
- 一起来学kafka之Kafka集群搭建
- 一起来学kafka之整合SpringBoot基本使用
- 一起来学kafka之整合SpringBoot深入使用(一)
- 一起来学kafka之整合SpringBoot深入使用(二)
- 一起来学kafka之整合SpringBoot深入使用(三)
项目源码(源码已更新 欢迎star⭐️)
ElasticSearch 专题学习
项目源码(源码已更新 欢迎star⭐️)
往期并发编程内容推荐
- Java多线程专题之线程与进程概述
- Java多线程专题之线程类和接口入门
- Java多线程专题之进阶学习Thread(含源码分析)
- Java多线程专题之Callable、Future与FutureTask(含源码分析)
- 面试官: 有了解过线程组和线程优先级吗
- 面试官: 说一下线程的生命周期过程
- 面试官: 说一下线程间的通信
- 面试官: 说一下Java的共享内存模型
- 面试官: 有了解过指令重排吗,什么是happens-before
- 面试官: 有了解过volatile关键字吗 说说看
- 面试官: 有了解过Synchronized吗 说说看
- Java多线程专题之Lock锁的使用
- 面试官: 有了解过ReentrantLock的底层实现吗?说说看
- 面试官: 有了解过CAS和原子操作吗?说说看
- Java多线程专题之线程池的基本使用
- 面试官: 有了解过线程池的工作原理吗?说说看
- 面试官: 线程池是如何做到线程复用的?有了解过吗,说说看
- 面试官: 阻塞队列有了解过吗?说说看
- 面试官: 阻塞队列的底层实现有了解过吗? 说说看
- 面试官: 同步容器和并发容器有用过吗? 说说看
- 面试官: CopyOnWrite容器有了解过吗? 说说看
- 面试官: Semaphore在项目中有使用过吗?说说看(源码剖析)
- 面试官: Exchanger在项目中有使用过吗?说说看(源码剖析)
- 面试官: CountDownLatch有了解过吗?说说看(源码剖析)
- 面试官: CyclicBarrier有了解过吗?说说看(源码剖析)
- 面试官: Phaser有了解过吗?说说看
- 面试官: Fork/Join 有了解过吗?说说看(含源码分析)
- 面试官: Stream并行流有了解过吗?说说看