責任練用來處理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.主管);
//我是主管,我每天幹人。
}
下圖舉工程師為例
- 一開始先跑責任鍊最外層的Boss.cs,判斷是否為老闆
- 判斷不是老闆
- 執行下一個責任Manager.cs的Job
- 判斷是否為主管
- 不是主管
- 執行下一個責任Engineer.cs的Job
- 判斷是否為工程師
- 是工程師,執行工程師的Work() => 我是工程師,每天寫Code