8、责任链模式
责任链模式(Chain of Responsibility Pattern)是一种行为型设计模式,它可以使多个对象都有机会处理请求。在 JavaScript 中,我们可以利用责任链模式来优化复杂、冗长的 if...else
语句。
在责任链模式中,各个处理者构成了一个链条,当有请求发生时,这些处理者按照顺序依次尝试处理请求,直到有处理者成功处理请求或所有处理者尝试完毕为止。因此,责任链模式可以动态地组织和修改处理流程,从而提高代码的灵活性。
在实际工作中,有很多场景可以使用责任链模式来优化复杂、冗长的 if...else
语句。
比如,在一个电商平台上,用户下单后需要进行一系列的校验和处理,比如校验商品库存是否充足、校验收货地址是否正确等。而这些校验和处理操作可能会有多个步骤,如果采用传统的 if...else
语句来实现,代码很容易变得冗长难懂。下面是一个简单的示例代码:
function placeOrder(order) { if (!order.items || !Array.isArray(order.items) || order.items.length === 0) { console.log("At least one item should be specified to place an order."); return; } // 校验商品库存是否充足 for (let i = 0; i < order.items.length; i++) { let item = order.items[i]; if (!checkStock(item.productId, item.quantity)) { console.log(`Product ${item.productId} is out of stock.`); return; } } if (!order.address || !isValidAddress(order.address)) { console.log("Invalid address."); return; } // 扣减库存 for (let i = 0; i < order.items.length; i++) { let item = order.items[i]; decreaseStock(item.productId, item.quantity); } // 生成订单 let orderId = generateOrderId(); console.log(`Order ${orderId} placed successfully.`); }
在上述代码中,我们使用了多个 if...else
语句来完成订单校验和处理操作。这样的代码难以维护和扩展,而且不符合开闭原则(对扩展开放,对修改关闭)。
使用责任链模式可以有效解决这个问题。下面是一个使用责任链模式来实现订单处理的示例代码:
class OrderValidator { constructor() { this.nextHandler = null; } setNext(handler) { this.nextHandler = handler; return handler; } handle(order) {} } class ItemValidator extends OrderValidator { handle(order) { if (!order.items || !Array.isArray(order.items) || order.items.length === 0) { console.log("At least one item should be specified to place an order."); return false; } else { return this.nextHandler.handle(order); } } } class StockValidator extends OrderValidator { handle(order) { for (let i = 0; i < order.items.length; i++) { let item = order.items[i]; if (!checkStock(item.productId, item.quantity)) { console.log(`Product ${item.productId} is out of stock.`); return false; } } return this.nextHandler.handle(order); } } class AddressValidator extends OrderValidator { handle(order) { if (!order.address || !isValidAddress(order.address)) { console.log("Invalid address."); return false; } else { return this.nextHandler.handle(order); } } } class StockDeductor extends OrderValidator { handle(order) { for (let i = 0; i < order.items.length; i++) { let item = order.items[i]; decreaseStock(item.productId, item.quantity); } return this.nextHandler.handle(order); } } class OrderGenerator extends OrderValidator { handle(order) { let orderId = generateOrderId(); console.log(`Order ${orderId} placed successfully.`); return true; } } let itemValidator = new ItemValidator(); let stockValidator = new StockValidator(); let addressValidator = new AddressValidator(); let stockDeductor = new StockDeductor(); let orderGenerator = new OrderGenerator(); itemValidator.setNext(stockValidator).setNext(addressValidator).setNext(stockDeductor).setNext(orderGenerator); function placeOrder(order) { itemValidator.handle(order); }
在上述代码中,我们定义了多个订单处理器(比如 ItemValidator
、StockValidator
等),它们继承自 OrderValidator
类。这些处理器构成了一个处理链,并通过 setNext()
方法连接起来。当用户下单后,我们只需要调用 placeOrder()
函数并将订单对象作为参数传入即可。
在处理过程中,每个处理器都会检查订单是否满足其要求。如果满足就继续交给下一个处理器去处理,否则直接返回。如果所有处理器都能够成功处理订单,最终会输出 “Order x placed successfully.” 的提示信息。
使用责任链模式的好处:
- 代码更加灵活和易于扩展:在需要添加或修改处理步骤时,只需要新增或修改相应的处理器类即可,不需要修改原有的代码。
- 代码复用性更高:不同的处理器类可以被复用,具有更好的可读性和可维护性。
- 代码结构更加清晰和易于理解:使用责任链模式将系统分解成多个小而简单的部分,每一个部分都有自己的处理逻辑和职责。这样的代码结构更加清晰和易于理解。
你今天学废了吗,end~