回到目錄
責任鏈模式
它是一種設計模塊,主要將操作流程與具體操作解耦,讓每個操作都可以設置自己的操作流程,這對于工作流應用是一個不錯的選擇!
下面是官方標準的定義:責任鏈模式是一種設計模式。在責任鏈模式里,很多對象由每一個對象對其下家的引用而連接起來形成一條鏈。請求在這個鏈上傳遞,直到鏈上的某一個對象決定處理此請求。發(fā)出這個請求的客戶端并不知道鏈上的哪一個對象最終處理這個請求,這使得系統(tǒng)可以在不影響客戶端的情況下動態(tài)地重新組織和分配責任。
使用場景
責任鏈模式在以下情況下可以被用到:
-
多個對象按照特定順序依次處理請求:當存在多個對象需要依次處理請求,并且每個對象都有可能處理請求或將請求傳遞給下一個對象時,責任鏈模式可以很好地組織和管理這些對象。
-
需要動態(tài)指定處理對象:責任鏈模式可以通過動態(tài)設置責任鏈的關系,靈活地指定處理對象??梢愿鶕?jù)實際情況動態(tài)增加、移除或調整處理者的順序,而不需要修改客戶端代碼。
-
避免請求發(fā)送者和接收者之間的耦合關系:使用責任鏈模式可以將請求發(fā)送者和接收者解耦,發(fā)送者只需要將請求發(fā)送給責任鏈的第一個處理者,而不需要關心具體是哪個處理者來處理請求。
-
處理請求的對象需要進行動態(tài)配置:責任鏈模式可以通過配置文件、數(shù)據(jù)庫等方式來動態(tài)配置處理者的順序和條件,而不需要修改代碼。
-
請求的處理邏輯具有變化和擴展的可能性:責任鏈模式可以很方便地對處理邏輯進行擴展和變化??梢酝ㄟ^增加新的處理者來擴展處理邏輯,也可以通過修改現(xiàn)有處理者的條件判斷來變化處理邏輯。
一些常見的使用場景包括:
- 客戶端請求的處理:比如Web請求處理、日志記錄、安全認證等。
- 錯誤處理和異常處理:將異?;蝈e誤從一個處理者傳遞給下一個處理者進行處理,直到找到能夠處理它的處理者。
- 負載均衡:按照一定策略將請求傳遞給多個服務器進行處理,直到有服務器能夠處理請求。
- 事件驅動系統(tǒng):通過觸發(fā)事件并將事件傳遞給相關的處理者來實現(xiàn)事件的處理和響應。
需要注意的是,責任鏈模式并不保證一定會有處理者能夠處理請求,因此需要在責任鏈末端進行處理請求無法被處理的情況。
實例中算法說明
- 每種handler只使用一次
- 按最高優(yōu)先級去使用,符合就用,不符合就走下一個策略
- 具體鏈條
- VipHandler >10000
- BigGiftHandler >1000
- DiscountHandler >200
- CouponHandler >100
- DiscountHandler >200
- BigGiftHandler >1000
- VipHandler >10000
代碼實現(xiàn)
- 定義處理請求的接口(Handler):
public interface Handler {
void handleRequest(Order order);
void setNextHandler(Handler nextHandler);
}
- 具體處理請求CouponHandler
public class CouponHandler implements Handler {
private static final Logger logger = LoggerFactory.getLogger(CouponHandler.class);
private Handler nextHandler;
@Override
public void handleRequest(Order order) {
// 這是可以想用多個責任鏈的實現(xiàn),如果是只使用1個,需要加上200的限制,就是每個訂單只能現(xiàn)用1種優(yōu)惠
if (order.getTotalPrice() >= 100) {
// 應用優(yōu)惠券打9折
order.setTotalPrice(order.getTotalPrice() * .9);
logger.info("Coupon 0.9 applied to order,{}", order.getOrderId());
}else if (nextHandler != null) {
nextHandler.handleRequest(order);
}
}
public void setNextHandler(Handler nextHandler) {
this.nextHandler = nextHandler;
}
}
- 具體處理請求DiscountHandler
public class DiscountHandler implements Handler {
private static final Logger logger = LoggerFactory.getLogger(CouponHandler.class);
private static final double DISCOUNT = .8;
private Handler nextHandler;
@Override
public void handleRequest(Order order) {
if (order.getTotalPrice() >= 200) {
// 應用折扣,折扣為標準的8折
order.setTotalPrice(order.getTotalPrice() * DISCOUNT);
logger.info("Discount 0.8 applied to order,{}", order.getOrderId());
}
else if (nextHandler != null) {
nextHandler.handleRequest(order);
}
}
public void setNextHandler(Handler nextHandler) {
this.nextHandler = nextHandler;
}
}
這個具體命令是可以擴展的,這也是職責鏈(責任鏈)的最重要的體現(xiàn)。
- 命令模式,方便將命令之久,及后期的動態(tài)配置
@Data
@AllArgsConstructor
public class HandlerModel implements Comparable<HandlerModel> {
private String title;
private String classPath;
private Integer sort;
@Override
public int compareTo(HandlerModel o) {
return o.getSort() - this.sort; // 降序
}
}
- 命令工廠,這里使用了強編碼的方式配置命令,真實項目中,這些命令可以配置到數(shù)據(jù)庫中
/**
* 折扣工廠.
*
* @author lind
* @date 2023/6/28 9:22
* @since 1.0.0
*/
public class HandlerFactory {
public static Handler handlerFactory() {
List<HandlerModel> handlerModels = new ArrayList<>();
handlerModels.add(
new HandlerModel("CouponHandler", "com.lind.common.pattern.chinaorder.handler.CouponHandler", 1));
handlerModels.add(
new HandlerModel("DiscountHandler", "com.lind.common.pattern.chinaorder.handler.DiscountHandler", 2));
handlerModels.add(
new HandlerModel("BigGiftHandler", "com.lind.common.pattern.chinaorder.handler.BigGiftHandler", 3));
handlerModels.add(
new HandlerModel("VipHandler", "com.lind.common.pattern.chinaorder.handler.VipHandler", 4));
return createHandler(handlerModels);
}
private static Handler createHandler(List<HandlerModel> handlerModels) {
Handler handler = null;
Handler previousHandler = null;
for (HandlerModel handlerModel : handlerModels.stream().sorted().collect(Collectors.toList())) {
try {
Handler currentHandler = (Handler) Class.forName(handlerModel.getClassPath()).newInstance();
if (previousHandler != null) {
previousHandler.setNextHandler(currentHandler);
}
else {
handler = currentHandler;
}
previousHandler = currentHandler;
}
catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
return handler;
}
}
- 看一下測試的代碼
public static void main(String[] args) {
Handler couponHandler = HandlerFactory.handlerFactory();
Order order1 = new Order("OR01", 150, true);
couponHandler.handleRequest(order1);
logger.info("order1:{}\n", order1.getTotalPrice());
Order order2 = new Order("OR02", 250, true);
couponHandler.handleRequest(order2);
logger.info("order2:{}\n", order2.getTotalPrice());
Order order3 = new Order("OR03", 50, true);
couponHandler.handleRequest(order3);
logger.info("order3:{}\n", order3.getTotalPrice());
Order order4 = new Order("OR04", 5001, true);
couponHandler.handleRequest(order4);
logger.info("order4:{}\n", order4.getTotalPrice());
Order order5 = new Order("OR05", 10001, true);
couponHandler.handleRequest(order5);
logger.info("order5:{}\n", order5.getTotalPrice());
文章來源:http://www.zghlxwxcb.cn/news/detail-504085.html
待續(xù)……
回到目錄文章來源地址http://www.zghlxwxcb.cn/news/detail-504085.html
到了這里,關于說說設計模式~責任鏈模式的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!