設計模式-責任鏈設計模式

責任鏈設計模式,是行爲型設計模式的巔峯之做。設計模式

如今有一個場景,請假申請。請假時間的長短,須要不一樣級別的領導才能審批。ide

萬物皆對象嘛,請假須要工號、姓名、緣由、時長、結果等等,那咱們來定義一個請假的類。其實其就是一個上下文環境(Context),保存業務處理中參數-----中間結果-----最終結果。行爲型設計模式重用的標配,把行爲轉移。this

public class ApplyContext
{
    public int Id { get; set; }
    public string Name { get; set; }
    /// <summary>
    /// 請假時長
    /// </summary>
    public int Hour { get; set; }
    public string Description { get; set; }
    public bool AuditResult { get; set; }
    public string AuditRemark { get; set; }
}

請假須要new一個實例:spa

 ApplyContext context = new ApplyContext()
 {
     Id = 506,
     Name = "bingle",
     Hour = 100,
     Description = "世界那麼大,我想去看看!",
     AuditResult = false,
     AuditRemark = ""
 };

第一種方式,審批邏輯都寫在上端,直接就是需求翻譯,沒有任何加工,談不上什麼擴展,面向過程:翻譯

 if (context.Hour <= 8)
 {
     Console.WriteLine("PM審批經過");
 }
 else if (context.Hour <= 16)
 {
     Console.WriteLine("主管審批經過");
 }
 else
 {
     Console.WriteLine("************");
 }

第二種方式,面向對象:封裝--繼承--多態,轉移業務邏輯,也只是一個翻譯機,翻譯完+面向對象,其實徹底沒有涉及加工沒有思考。設計

領導類S:code

 public class PM
 {
     public override void Audit(ApplyContext context)
     {
         Console.WriteLine($"This is {this.GetType().Name} {this.Name} Audit");
         if (context.Hour <= 8)
         {
             context.AuditResult = true;
             context.AuditRemark = "容許請假!";
         }
     }   
}


 public class Charge
 {
     public override void Audit(ApplyContext context)
     {
         Console.WriteLine($"This is {this.GetType().Name} {this.Name} Audit");
         if (context.Hour <= 16)
         {
             context.AuditResult = true;
             context.AuditRemark = "容許請假!";
         }
    }
}


 public class Manager 
 {
     public override void Audit(ApplyContext context)
     {
         Console.WriteLine($"This is {this.GetType().Name} {this.Name} Audit");
         if (context.Hour <= 24)
         {
             context.AuditResult = true;
             context.AuditRemark = "容許請假!";
         }
    }
}


 public class Chief
 {
     public override void Audit(ApplyContext context)
     {
         Console.WriteLine($"This is {this.GetType().Name} {this.Name} Audit");
         if (context.Hour <= 48)
         {
             context.AuditResult = true;
             context.AuditRemark = "容許請假!";
         }
    }
}



 public class CEO : AbstractAuditor
 {
     public override void Audit(ApplyContext context)
     {
         Console.WriteLine($"This is {this.GetType().Name} {this.Name} Audit");
         if (context.Hour <= 96)
         {
             context.AuditResult = true;
             context.AuditRemark = "容許請假!";
         }
    }
}


public class ChiarMan : AbstractAuditor
{
    public override void Audit(ApplyContext context)
    {
        Console.WriteLine($"This is {this.GetType().Name} {this.Name} Audit");
        if (context.Hour <= 1000000)
        {
            context.AuditResult = true;
            context.AuditRemark = "容許請假!";
        }
    }
}
View Code

下面進行邏輯的翻譯:對象

 AbstractAuditor pm = new PM()
 {
     Name = "bingle1"
 };
 pm.Audit(context);
 if (!context.AuditResult)
 {
     AbstractAuditor charge = new Charge()
     {
         Name = "bingle2"
     };
     charge.Audit(context);
     if (!context.AuditResult)
     {
         AbstractAuditor manager = new Manager()
         {
             Name = "bingle3"
         };
         manager.Audit(context);
         if (!context.AuditResult)
         {
             //找下一環節
         }
     }
 }

不要直接翻譯的邏輯,須要涉及,如今的場景分析是,一、權限範圍內,審批經過;二、權限範圍外,交給下一環節審批,寫的代碼又多了一個,指定洗衣環節,甩鍋大法開始。blog

首先定義一個抽象父類:繼承

public abstract class AbstractAuditor
{
    public string Name { get; set; }
    public abstract void Audit(ApplyContext context);

    private AbstractAuditor _NextAuditor = null;
    public void SetNext(AbstractAuditor auditor)
    {
        this._NextAuditor = auditor;
    }
    protected void AuditNext(ApplyContext context)
    {
        if (this._NextAuditor != null)
        {
            this._NextAuditor.Audit(context);
        }
        else
        {
            context.AuditResult = false;
            context.AuditRemark = "不容許請假!";
        }
    }
}

領導類須要繼承這個抽象類:

 public class PM : AbstractAuditor
 {
     public override void Audit(ApplyContext context)
     {
         Console.WriteLine($"This is {this.GetType().Name} {this.Name} Audit");
         if (context.Hour <= 8)
         {
             context.AuditResult = true;
             context.AuditRemark = "容許請假!";
         }
         else
         {
             AbstractAuditor charge = new Charge()
             {
                 Name = "象撲君"
             };
             charge.Audit(context);
         }
     }
 }

 

其餘的領導類以此類推.....

調用的時候,只須要找最低權限的人,去審批

AbstractAuditor pm = new PM()
{
    Name = "bingle"
};
pm.Audit(context);

以上,轉移了申請提交的邏輯,此次符合實際狀況,有了本身的思考和設計在裏面。

 

甩鍋大法開始了,同樣,領導類須要實現抽象父類,不過在Audit方法中稍做了改動

 public class PM : AbstractAuditor
 {
     public override void Audit(ApplyContext context)
     {
         Console.WriteLine($"This is {this.GetType().Name} {this.Name} Audit");
         if (context.Hour <= 8)
         {
             context.AuditResult = true;
             context.AuditRemark = "容許請假!";
         }
         else
         {
             base.AuditNext(context);
         }
     }
 }



 public class Manager : AbstractAuditor
 {
     public override void Audit(ApplyContext context)
     {
         Console.WriteLine($"This is {this.GetType().Name} {this.Name} Audit");
         if (context.Hour <= 24)
         {
             context.AuditResult = true;
             context.AuditRemark = "容許請假!";
         }
         else
         {
             base.AuditNext(context);
         }
     }
 }


public class Chief : AbstractAuditor
{
    public override void Audit(ApplyContext context)
    {
        Console.WriteLine($"This is {this.GetType().Name} {this.Name} Audit");
        if (context.Hour <= 48)
        {
            context.AuditResult = true;
            context.AuditRemark = "容許請假!";
        }
        else
        {
            base.AuditNext(context);
        }
    }
}


public class ChiarMan : AbstractAuditor
{
    public override void Audit(ApplyContext context)
    {
        Console.WriteLine($"This is {this.GetType().Name} {this.Name} Audit");
        if (context.Hour <= 1000000)
        {
            context.AuditResult = true;
            context.AuditRemark = "容許請假!";
        }
        else
        {
            base.AuditNext(context);
        }
    }
}


 public class Charge: AbstractAuditor
 {
     public override void Audit(ApplyContext context)
     {
         Console.WriteLine($"This is {this.GetType().Name} {this.Name} Audit");
         if (context.Hour <= 16)
         {
             context.AuditResult = true;
             context.AuditRemark = "容許請假!";
         }
         else
         {
             base.AuditNext(context);
         }
     }
 }

 public class CEO : AbstractAuditor
 {
     public override void Audit(ApplyContext context)
     {
         Console.WriteLine($"This is {this.GetType().Name} {this.Name} Audit");
         if (context.Hour <= 96)
         {
             context.AuditResult = true;
             context.AuditRemark = "容許請假!";
         }
         else
         {
             base.AuditNext(context);
         }
     }
 }
View Code

下面須要找領導審批了:

AbstractAuditor pm = new PM()
{
    Name = "bingle1"
};
AbstractAuditor charge = new Charge()
{
    Name = "bingle1"
};
AbstractAuditor manager = new Manager()
{
    Name = "bingle1"
};
AbstractAuditor chief = new Chief()
{
    Name = "bingle1"
};
AbstractAuditor ceo = new CEO()
{
    Name = "bingle1"
};

//pm.SetNext(charge);
//charge.SetNext(manager);
pm.SetNext(manager);
manager.SetNext(chief);
chief.SetNext(ceo);
ceo.SetNext(new ChiarMan()
{
    Name = "bingle1"
});
//流程的可擴展

pm.Audit(context);

 if (!context.AuditResult)
 {
     Console.WriteLine("不幹了!");
 }

以上,把流暢環節邏輯從業務類轉移了。

相關文章
相關標籤/搜索