facade

第十二章 外观模式(Facade Pattern)

1 概要

外观模式(Facade Pattern)是一种结构性的模式(Structural Design Pattern),它能将系统以一个统一的接口向外提供服务,以方便其他模块使用。

在大型系统设计中,开发人员往往会将大的系统分解为多个较小的子系统,以降低开发难度。然而,各子系统之间存在着相互依赖。往往这些复杂的依赖关系会使得系统逻辑变得非常复杂。使用外观模式能帮助简化各子系统之间的接口,降低开发的难度。

例如:假设有一个电子商务系统。它支持用户在移动设备、台式电脑和应用程序访问查看用户的支付记录,订单情况和浏览商品信息。如图一中左侧图片所示,如果不使用外观模式,用户需要直接与商品模块、订单模块和支付模块直接交互。这样的设计会使得系统流程过于复杂,难以维护。如果在用户与系统之间增加一层外观层,如图一中右侧图片所示,用户只与外观模型交互。在系统内部,各模块也只从外观模块接收用户请求。这样的设计使得系统各模块之间的职责和处理流程更加清晰。

图一 外观模式解决方案

图一 外观模式解决方案。

2 外观模式的结构

在外观模式中,有三类参与方。

  1. Facade接口接收客户端的请求,并将其分发给相应的子系统。
  2. SubSystem是完成真实逻辑的代码。它"隐藏"在Facade接口背后。
  3. Client(客户)则向Facade发送请求,使用SubSystem的功能。

图一 外观模式结构

图二 外观模式结构。

3 外观模式示例

我们使用一个简单的用例来展示外观模式的用法。这个用例实现了一个简单的在线商店的功能。在这个在线商店中,用户可以查看商品的库存、购买商品、支付订单等服务。因此,我们定义了InventoryService, PaymentService和ShippingService。它们是这个在线商店的子系统,我们只定义了一个方法作为示例。

public class InventoryService {
    // 查看商品库存
    public static Long availability(Long productId);
	...
}

public class PaymentService {
    // 支付账单
    public static Boolean makePayment(Long orderId, Long quantity);
	...
}

public class ShippingService {
    // 将商品加入购物车
    public static Boolean shipProduct(Long productId, Long quantity);
	...
}

然后,该示例还定义了一个外观模式的OrderServiceFacadeItf接口。作为子模块,InventoryService、PaymentService和ShippingService可能提供更多接口和服务,然而,在这个在线商店的应用中,可能只需要支持和实现几种处理流程。因此,在OrderServiceFacadeItf接口中,我们只定义了一个接口方法placeOrder(),提供完成订单服务。在OrderServiceFacadeImpl中,它通过使用InventoryService、PaymentService和ShippingService子系统实现了订单服务。

interface OrderServiceFacadeItf {
    Boolean placeOrder(Long productId);
}

public class OrderServiceFacadeImpl implements OrderServiceFacadeItf {
    @Override
	public Boolean placeOrder(Long productId, Long quantity) {
	    if (InventoryService.availability(productId) >= quantity) {
            Boolean paymentConfirmed = PaymentService.makePayment();
            if (paymentConfirmed) {
                ShippingService.shipProduct(productId, quantity);
                return true;
            }
        }
        
        return false;
	}
}

使用外观模式的好处体现在OrderServiceFullfillmentClient类中。该类使用了外观模式提供的接口完成订单。在OrderServiceFullfillmentClient中,它并不需要知道订单是如何完成的,也不需要知道InventoryService、PaymentService和ShippingService子系统的存在和它们的使用方法。因此,外观模式能简化客户端的开发,分离业务逻辑和实现细节。

public class OrderServiceFullfillmentClient {
    OrderServiceFacadeItf facade = new OrderServiceFacadeImpl();
    if (facade.placeOrder(12345, 1)) {
        System.out.println("A new order has been successfully created.");
    }
}

4 小结

本章介绍了外观模式的结构和使用方法。外观模式的优点是它能将各个实现的子系统包装"隐藏"起来,客户端可以直接使用外观模式提供的接口,而无需了解其背后的实现原理和细节。这种设计方法有助于简化系统的实现。

 

上一章
下一章

注册用户登陆后可留言

Copyright  2019 Little Waterdrop, LLC. All Rights Reserved.