Java教程

设计模式-职责链模式

本文主要是介绍设计模式-职责链模式,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

一、定义

职责链模式:使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系。将这个对象连成一条链,并沿着这条链传递该请求,直到结束。

二、代码实现

UML类图

定义一个抽象类AbstractHandler,提供一个对外方法handleRequest(),处理外部请求。抽象类分别有三个具体实现类,GuestHandler、CustomerHandler、MerchantHandler对应三种条件下的处理逻辑,如果不采用职责链设计模式,那么通常就是通过if...else...实现,if customer ... else if merchant ... else if guest ... else ...

职责链设计模式,当提交一个请求时,由第一个AbstractHandler实现类处理,如果满足条件则处理返回,否则移交给下一个AbstractHandler实现类处理,直至没有下一个。这样设计的好处符合开闭原则,每当新增一种条件,只需要增加一个AbstractHandler实现类,而不需要改动已有类,对拓展开放对修改封闭。

import com.tj.designpatterns.chofresb.model.HandlerRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

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);

}

如果是hit一个handler类后,需要继续判断其他的handler类,满足hit条件的handler类都需要执行handleRequest,只需要在handle(request)后,不立即return即可,稍微调整也可以满足需求。
其实,根据个人理解,职责链模式应该是需要依次执行每一个handler类的,完成每个handler判断是否hit来决定执行handle方法,如果是满足其中一个handler就立即退出的,更应该用策略设计模式,选择合适的策略handler类执行对应的handle方法。

import com.tj.designpatterns.chofresb.model.HandlerRequest;
import com.tj.designpatterns.chofresb.model.UserRole;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Primary;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

@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);
    }
}
import com.tj.designpatterns.chofresb.model.HandlerRequest;
import com.tj.designpatterns.chofresb.model.UserRole;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

@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);
    }
}
import com.tj.designpatterns.chofresb.model.HandlerRequest;
import com.tj.designpatterns.chofresb.model.UserRole;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

@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确定前后顺序。

import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.AnnotationAwareOrderComparator;

import java.util.List;


@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很好的结合。

这篇关于设计模式-职责链模式的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!