設計模式 - 責任鍊模式 (Behavioral Patterns - Chain of Responsibility Pattern)

前言

我們先從Chain of Responsibility字面定義來看這個設計模式,他有責任還有鍊,那代表可能他會將不同的演算法串起來,所以這個模式我們可以猜測這個模式的設計會圍繞

  • 如何讓每個演算法串起來
    • 如何串
    • 串起來的優點

而果不其然,責任鍊模式的定義如下

  • 避免耦合,將每個呼叫的要求透過鍊的概念傳遞
  • 每個邏輯流程會由多個handler串起
  • 會透過recrsive的方式詢問全部的handler

類別圖

  • 定義出Handler要被外部(其他handler)呼叫的介面
  • 而Handler聚合的方法會有點類似LinkedList,對綁定在自己下方的Handler呼叫

範例

我們來想一下英雄遊戲可以使用責任鍊模式,我想武器鍛造應該很適合
武器鍛造流程

  • 打鐵 (機率提升攻擊)
  • 鑲寶石 (機率提升特殊效果)
  • 加把手 (機率提升命中)
  • 取出 (出貨)

所以我們會有四個handler,依照順序包裝我們的handler,執行

abstract class Handler {
    Handler nextHandler = null;

    public Handler(Handler nextHandler) {
        this.nextHandler = nextHandler;
    }

    public void execute() {
        action();
        if (nextHandler != null) {
            nextHandler.execute();
        }
    }

    abstract void action();
}

class ImproveAttackHandler extends Handler {

    public ImproveAttackHandler(Handler nextHandler) {
        super(nextHandler);
    }

    @Override
    void action() {
        System.out.println("Improve attack ability");
    }
}

class HitsRateHandler extends Handler {

    public HitsRateHandler(Handler nextHandler) {
        super(nextHandler);
    }

    @Override
    void action() {
        System.out.println("Improve hits rate ability");
    }
}

class SpecialAbilityHandler extends Handler {

    public SpecialAbilityHandler(Handler nextHandler) {
        super(nextHandler);
    }

    @Override
    void action() {
        System.out.println("Add special ability");
    }
}

class FinishHandler extends Handler {

    public FinishHandler(Handler nextHandler) {
        super(nextHandler);
    }

    @Override
    void action() {
        System.out.println("Take out weapon from smithy");
    }
}

public class ChainOfResponsibility {
    public static void main(String[] args) {
        System.out.println("Start to make a weapon");
        Handler handler = new ImproveAttackHandler(
                new SpecialAbilityHandler(
                        new HitsRateHandler(
                                new FinishHandler(null)
                        )
                )
        );
        handler.execute();
    }
}

原始碼

結論

責任鍊模式的優點在於

  • 將邏輯物件話包裝
    • 可以動態新增或刪減

缺點

  • 包裝的過程可能要思考一下會比較容易閱讀,像是範例的main就不是很優雅

留言

這個網誌中的熱門文章

Java Lambda Map篇

(InterviewBit) System Design - Design Cache System

設計模式 - 享元模式 (Structural Patterns - Flyweight Design Pattern)