Java設計模式學習 - 責任鏈模式

我的博客項目地址html

但願各位幫忙點個star,給我加個小星星✨java


設計模式-責任鏈git


簡單介紹

責任鏈模式(Chain of Responsibility):使多個對象都有機會處理同一個請求,從而避免請求的發送者和接收者之間的耦合關係。將這些對象連成一條鏈,並沿着這條鏈傳遞該請求,直到有一個對象處理它爲止。github


舉個🌰

一節課堂,有課前、課中和課後,不一樣老師、不一樣地點或者不一樣時間,課堂的內容和實際都有所不一樣,若是在一個service中寫業務邏輯,代碼可讀性會比較差,別人維護也麻煩,因此使用責任鏈模式,將每一步分開維護,大概流程以下:設計模式

  • 編寫課程前、中、後的執行邏輯和回滾邏輯
  • 一個業務結束後,調用下一個業務的執行邏輯
  • 一個業務失敗後,調用上一個業務的回滾邏輯

PS:左邊的課程和規則是一個總體,責任鏈真正處理的流程是右邊的邏輯。ide


實現代碼

這個例子還用到了工廠方法和單例方法,以及與Spring整合了,各位看官在實際使用中,要根據自身狀況,適當的修改。this

抽象RuleHandler

/** * @author JingQ at 2018/9/7 */
public abstract class AbstractRuleHandler {

    /** * 上一個處理器 */
    private AbstractRuleHandler preHandler;

    /** * 下一個處理器 */
    private AbstractRuleHandler nextHandler;

    /** * 責任鏈模式 * @param experiment experiment */
    public void doHandler(Experiment experiment, ClassRule rule) {
        try {
            doHandleReal(experiment, rule);
        } catch (Exception e) {
            rollBack(experiment, rule);
            return;
        }
        if (nextHandler != null) {
            nextHandler.doHandler(experiment, rule);
        }
    }

    /** * 回滾策略 * @param experiment experiment * @param rule rule */
    public void rollBack(Experiment experiment ,ClassRule rule) {
        rollBackReal(experiment, rule);
        if (preHandler != null) {
            preHandler.rollBack(experiment, rule);
        }
    }

    /** * 真正處理的邏輯 * @param experiment experiment * @param rule 規則 */
    public abstract void doHandleReal(Experiment experiment, ClassRule rule);

    /** * 回滾邏輯 * @param experiment experiment * @param rule 規則 */
    public abstract void rollBackReal(Experiment experiment, ClassRule rule);

    public AbstractRuleHandler setPreHandler(AbstractRuleHandler preHandler) {
        this.preHandler = preHandler;
        return preHandler;
    }

    public AbstractRuleHandler setNextHandler(AbstractRuleHandler nextHandler) {
        this.nextHandler = nextHandler;
        nextHandler.setPreHandler(this);
        return nextHandler;
    }
}
複製代碼

第一個Handler

@Service
public class ClassBeginRuleHandler extends AbstractRuleHandler {

    @Override
    public void doHandleReal(Experiment experiment, ClassRule rule) {
        experiment.setName(rule.getRule1());
        System.out.println("success rule1 : " + rule.getRule1());
    }

    @Override
    public void rollBackReal(Experiment experiment, ClassRule rule) {
        System.out.println("error rule1 : " + rule.getRule1());
    }
}
複製代碼

因爲第二個與第一個處理同樣,就不貼出來了spa


第三個Handler

@Service
public class ClassEndRuleHandler extends AbstractRuleHandler {

    @Autowired
    private ClassroomService classroomService;

    @Override
    public void doHandleReal(Experiment experiment, ClassRule rule) {
        Classroom classroom = classroomService.getById(experiment.getClassroomId());
        if (classroom != null) {
            if (StringUtils.equals(classroom.getClassroom(), rule.getRule3())) {
                experiment.setClassroomId(classroom.getId());
            }
            System.out.println(classroom.getClassroom() + "-" + rule.getRule3());
        } else {
            System.out.println("classroom is null , success rule 3 :"  + rule.getRule3());
        }
    }

    @Override
    public void rollBackReal(Experiment experiment, ClassRule rule) {
        System.out.println("error Rule 3 : " + rule.getRule3());
    }
}
複製代碼

工廠整合類

/** * 工廠方法 * @author JingQ at 2018/9/7 */
@Service
public class AbstractRuleFactory {

    @Autowired
    private ClassEndRuleHandler classEndRuleHandler;

    @Autowired
    private ClassingRuleHandler classingRuleHandler;

    @Autowired
    private ClassBeginRuleHandler classBeginRuleHandler;

    private AbstractRuleHandler ruleHandler;

    private AbstractRuleFactory() {
    }

    // 使用了單例模式
    public AbstractRuleHandler getInstance() {
        if (ruleHandler == null) {
            synchronized (AbstractRuleFactory.class) {
                if (ruleHandler == null) {
                    ruleHandler = classBeginRuleHandler;
                    ruleHandler.setNextHandler(classingRuleHandler).setNextHandler(classEndRuleHandler);
                }
            }
        }
        return ruleHandler;
    }
}
複製代碼

執行效果

能夠看到,經過factory.getInstance().doHandle(experiment, rule),責任鏈會根據設定的順序進行執行,每一個業務操做都進行分開了,代碼也更加整潔,維護性也更強了。.net


參考資料

  1. Java設計模式----責任鏈模式
  2. Java設計模式應用——責任鏈模式
相關文章
相關標籤/搜索