iT邦幫忙

2023 iThome 鐵人賽

DAY 19
0
自我挑戰組

Design Pattern - 無所不在的設計模式系列 第 19

[Day19] Design Pattern - Chain of Responsibility 責任鏈模式

  • 分享至 

  • xImage
  •  

前言

今天學到了好多社會化的東西(告誡)
還有回話時不要傻住的藝術(??

定義


Chain of Responsibility is a behavioral design pattern that lets you pass requests along a chain of handlers. Upon receiving a request, each handler decides either to process the request or to pass it to the next handler in the chain.
--Refactoring Guru

責任鏈(Chain of Responsibility)是一種行為型設計模式,它允許你將請求依次傳遞給一系列處理者。在收到請求後,每個處理者決定是處理該請求還是將其傳遞給鏈中的下一個處理者。

在這種設計模式中,通常每個接收者包含對另一個接收者的reference。
如果一個接收者無法處理請求,它會將相同的請求傳遞給下一個接收者(像接力一樣)。
一個接收者處理了鏈中的請求,或者一個或多個接收者處理了該請求。

圖例

請看下圖~

從這張圖可以看到,客戶端送出了請求到接收者鍊,
在這串接收者中,請求會先送給接收者1 (Receiver 1),接收者1會先確認它能否處理這筆請求,
如果接收者1可以處理,那它就會處理它然後檢查後續程序會不會需要這個請求。
假如接收者2要的話,那這筆請求接收者2也會使用;反之,如果接收者2不需要的話,那接收者2就會傳遞這筆請求給下一個接收者。

UML


C#小遊戲例子~


我們來用一個小遊戲舉例吧~

假設我們有一個遊戲中的角色,
這個角色可以使用不同類型的武器攻擊敵人,而不同的敵人擁有不同的防禦能力。
我們可以使用責任鏈模式來模擬這種情境,以確定哪種武器可以擊敗哪種敵人!

首先,我們需要定義抽象處理器 WeaponHandler,然後有具體處理器 SwordHandlerBowHandlerMagicHandler,它們分別代表不同類型的武器。
最後,有一個 Enemy 類表示敵人,每個敵人都有一個防禦等級。

// 定義抽象處理器
abstract class WeaponHandler
{
    protected WeaponHandler nextHandler;

    public void SetNextHandler(WeaponHandler handler)
    {
        nextHandler = handler;
    }

    public abstract void HandleAttack(Enemy enemy);
}

再來是我們各個具體武器處理者

// 具體處理器:劍
class SwordHandler : WeaponHandler
{
    public override void HandleAttack(Enemy enemy)
    {
        if (enemy.Defense <= 10)
        {
            Console.WriteLine("使用劍攻擊敵人!");
        }
        else if (nextHandler != null)
        {
            Console.WriteLine("劍無法擊敗這個敵人,嘗試下一種武器。");
            nextHandler.HandleAttack(enemy);
        }
    }
}

// 具體處理器:弓箭
class BowHandler : WeaponHandler
{
    public override void HandleAttack(Enemy enemy)
    {
        if (enemy.Defense <= 20)
        {
            Console.WriteLine("使用弓箭攻擊敵人!");
        }
        else if (nextHandler != null)
        {
            Console.WriteLine("弓箭無法擊敗這個敵人,嘗試下一種武器。");
            nextHandler.HandleAttack(enemy);
        }
    }
}

// 具體處理器:魔法
class MagicHandler : WeaponHandler
{
    public override void HandleAttack(Enemy enemy)
    {
        if (enemy.Defense <= 30)
        {
            Console.WriteLine("使用魔法攻擊敵人!");
        }
        else
        {
            Console.WriteLine("魔法無法擊敗這個敵人,需要更強力的武器。");
        }
    }
}

來創一個敵人:

// 敵人類
class Enemy
{
    public int Defense { get; set; }

    public Enemy(int defense)
    {
        Defense = defense;
    }
}

最後我們的客戶端程式碼~

class Program
{
    static void Main(string[] args)
    {
        // 創建武器處理鏈
        WeaponHandler swordHandler = new SwordHandler();
        WeaponHandler bowHandler = new BowHandler();
        WeaponHandler magicHandler = new MagicHandler();

        swordHandler.SetNextHandler(bowHandler);
        bowHandler.SetNextHandler(magicHandler);

        // 創建不同防禦等級的敵人
        Enemy enemy1 = new Enemy(5);
        Enemy enemy2 = new Enemy(15);
        Enemy enemy3 = new Enemy(25);

        // 使用不同武器攻擊敵人
        swordHandler.HandleAttack(enemy1);
        swordHandler.HandleAttack(enemy2);
        swordHandler.HandleAttack(enemy3);
    }
}

這個例子中,我們建立了一個武器處理鏈,
每個武器處理器可以根據敵人的防禦等級,決定是否使用該武器攻擊敵人。
如果一個武器無法擊敗敵人,它將把攻擊傳遞給下一個武器。
這種方式類似於責任鏈模式,讓不同的處理器依次處理攻擊請求,直到找到適合的武器~


上一篇
[Day18] Design Pattern - Proxy代理模式
下一篇
[Day20] Design Pattern - Command命令模式
系列文
Design Pattern - 無所不在的設計模式30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言