一、定義
職責鏈模式:使多個物件都有機會處理請求,從而避免請求的傳送者和接受者之間的耦合關係。將這個物件連成一條鏈,並沿著這條鏈傳遞該請求,直到有一個物件處理它為止。
二、程式碼實現
定義一個抽象類AbstractHandler,提供一個對外方法handleRequest(),處理外部請求。抽象類分別有三個具體實現類,GuestHandler、CustomerHandler、MerchantHandler對應三種條件下的處理邏輯,如果不採用職責鏈設計模式,那麼通常就是通過if…else…實現,if customer … else if merchant … else if guest … else …
職責鏈設計模式,當提交一個請求時,由第一個AbstractHandler實現類處理,如果滿足條件則處理返回,否則移交給下一個AbstractHandler實現類處理,直至沒有下一個。這樣設計的好處符合開閉原則,每當新增一種條件,只需要增加一個AbstractHandler實現類,而不需要改動已有類,對擴充開放對修改封閉。
public abstract class AbstractHandler {
private static final Logger log = LoggerFactory.getLogger(AbstractHandler.class);
private AbstractHandler next;
public AbstractHandler getNext() {
return next;
}
public void setNext(AbstractHandler next) {
this.next = next;
}
public void handleRequest(HandlerRequest request) {
if (isHit(request)) {
this.handle(request);
return;
}
if (this.next != null) {
this.next.handleRequest(request);
} else {
log.warn("no handler execute, request: {}", request);
}
}
protected abstract boolean isHit(HandlerRequest request);
protected abstract void handle(HandlerRequest request);
}
@Primary
@Order(1)
@Component
public class CustomerHandler extends AbstractHandler {
private static final Logger log = LoggerFactory.getLogger(CustomerHandler.class);
@Override
protected boolean isHit(HandlerRequest request) {
return request.getUserRole() == UserRole.CUSTOMER;
}
@Override
protected void handle(HandlerRequest request) {
log.info("handle customer execute, request: {}", request);
}
}
@Order(2)
@Component
public class MerchantHandler extends AbstractHandler {
private static final Logger log = LoggerFactory.getLogger(MerchantHandler.class);
@Override
protected boolean isHit(HandlerRequest request) {
return request.getUserRole() == UserRole.MERCHANT;
}
@Override
protected void handle(HandlerRequest request) {
log.info("handle merchant execute, request: {}", request);
}
}
@Order(3)
@Component
public class GuestHandler extends AbstractHandler {
private static final Logger log = LoggerFactory.getLogger(GuestHandler.class);
@Override
protected boolean isHit(HandlerRequest request) {
return request.getUserRole() == UserRole.GUEST;
}
@Override
protected void handle(HandlerRequest request) {
log.info("handle guest execute, request: {}", request);
}
}
如果是在springboot的實際專案中,可以通過再增加一個配置類初始化將AbstractHandler各個實現類鏈起來,利用@Order確定前後順序。
@Configuration
public class InitConfigHandler implements InitializingBean {
@Autowired
private List<AbstractHandler> abstractHandlerList;
@Override
public void afterPropertiesSet() throws Exception {
abstractHandlerList.sort(AnnotationAwareOrderComparator.INSTANCE);
int size = abstractHandlerList.size();
for (int i = 0; i < size - 1; i++) {
abstractHandlerList.get(i).setNext(abstractHandlerList.get(i + 1));
}
}
}
這樣當需要注入使用AbstractHandler類時,預設會注入@Primary的類作為職責鏈的第一鏈。實現了職責鏈模式與springboot很好的結合。
本作品採用《CC 協議》,轉載必須註明作者和本文連結