一起来学设计模式之外观模式

416 阅读8分钟

前言

目前正在出一个设计模式专题系列教程, 篇幅会较多, 喜欢的话,给个关注❤️ ~

本节给大家讲一下设计模式中的外观模式,并结合实际业务场景给大家讲解如何使用~

本专题的所有案例代码主要以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 专题学习

项目源码(源码已更新 欢迎star⭐️)

ElasticSearch 专题学习

项目源码(源码已更新 欢迎star⭐️)

往期并发编程内容推荐

推荐 SpringBoot & SpringCloud (源码已更新 欢迎star⭐️)

博客(阅读体验较佳)