責任練簡單範例

責任練用來處理Switch case時可以攤平所有處理程序

優缺點??

 

假設原本有一個流程 他會根據公司不同的位階有不同的工作

先寫好一個Enum代表工作

public enum JobEnum
{
    老闆=1,
    主管,
    工程師
}

 這時候如果用Switch Case會怎麼寫?

public void Example_Switch_Case(JobEnum title)
{
    switch (title)
    {
        case JobEnum.老闆:
            //老闆的工作
            break;
        case JobEnum.主管:
            //主管的日常
            break;
        case JobEnum.工程師:
            //工程師的苦命
            break;
        default:
            break;
    }
}

如果改成責任練模式,他會把流程串起來,一個一個去檢查,如果符合他的位階,就會做工作,否則往下丟給下一個位階。

我們先建立一個abstract父類別 Job,給各個職稱去繼承

 public abstract class Job
 {
     //下一個責任
     private readonly Job nextJob;
     protected abstract void Work();
     protected abstract bool IsMyJob(JobEnum title);


     /// <summary>
     /// 建構式
     /// </summary>
     /// <param name="_nextJob">下個責任</param>
     public Job(Job _nextJob)
     {
         //在建構式中指定下個責任
         nextJob = _nextJob;
     }

     public void DoingTheirJob(JobEnum title)
     {
         //判斷是否為自己的責任
         if (IsMyJob(title))
         {
             Work(); //是的話就做自己的Work
         }
         else
         {
             if (nextJob != null)  
             {
                 nextJob.DoingTheirJob(title);  //做下一個責任的處理
             }
             else
             {
                 Debug.WriteLine("責任練結束"); //如果已經沒有下個責任 結束
             }
         }
     }
 }

其中Work和IsMyJob兩個abstract method在子類別中去override,做他們該做的工作
我們就相對應Enum三個位階做出三個子類別

/// <summary>
/// 老闆
/// </summary>
public class Boss :Job
{
    public Boss(Job job):base(job)
    {
    }

    protected override bool IsMyJob(JobEnum title)
    {
        return title == JobEnum.老闆;
    }

    protected override void Work()
    {
        Debug.WriteLine($"我是老闆,我每天數鈔票。");
    }
}
/// <summary>
/// 主管
/// </summary>
public class Manager : Job
{
    public Manager(Job job) :base(job)
    {
    }

    protected override bool IsMyJob(JobEnum title)
    {
      return title == JobEnum.主管;
    }

    protected override void Work()
    {
        Debug.WriteLine($"我是主管,我每天幹人。");
    }
}
/// <summary>
/// 工程師
/// </summary>
public class Engineer : Job
{
    public Engineer(Job job): base(job)
    {
    }

    protected override bool IsMyJob(JobEnum title)
    {
        return JobEnum.工程師 == title;
    }

    protected override void Work()
    {
        Debug.WriteLine($"我是工程師,每天寫Code");
    }
}

到這邊我們已經把責任鍊的物件建立完成,實際在使用時



//實際可以這樣寫
public class JobFlow
{
    private Job job;
    public JobFlow()
    {
        //建構式建立好責任鍊的流程
        job = new Boss(new Manager(new Engineer(null)));
    }

    public void CurrentWork(JobEnum title)
    {
        //根據位階做自己的事情
        job.DoingTheirJob(title);
    }
}

public static void main()
{
    JobFlow flow = new JobFlow();

    flow.CurrentWork(JobEnum.工程師);
    //我是工程師,每天寫Code

    flow.CurrentWork(JobEnum.主管);
    //我是主管,我每天幹人。
}

 下圖舉工程師為例

  1. 一開始先跑責任鍊最外層的Boss.cs,判斷是否為老闆​
  2. 判斷不是老闆
  3. 執行下一個責任Manager.cs的Job
  4. 判斷是否為主管
  5. 不是主管
  6. 執行下一個責任Engineer.cs的Job
  7. 判斷是否為工程師
  8. 是工程師,執行工程師的Work()  => 我是工程師,每天寫Code