深入理解C#設計模式之策略模式 角色具體案例分享

來源:互聯網
上載者:User
策略模式(Stragety Pattern)

策略模式屬於行為型模式,它定義了一系列的演算法,並將每一個演算法封裝起來,而且使他們可以相互替換,讓演算法獨立於使用它的客戶而獨立變化。

使用原則模式可以把行為和環境分割開來。環境類負責維持和查詢行為類,各種演算法則在具體策略類中提供。

角色:

1、抽象策略(Strategy)

這是一個抽象角色,通常由一個介面或抽象類別實現。此角色給出所有的具體策略類所需的介面;

2、具體策略(Concrete Strategy)

實現抽象策略的具體策略類,封裝了相關的演算法或行為;

3、環境類(Context)

持有一個Strategy類的引用並可以根據邏輯選擇執行個體相應的策略。

樣本:

命名空間StragetyPattern中包含策略基類Tax以及它的8個實作類別,Context環境類持有策略基類。本樣本通過一個優雅的方式來計算個人所得稅。

C#開發筆記之04-如何用C#優雅的計算個人所得稅?

namespace StragetyPattern
public abstract class Tax {    protected decimal TaxRate = 0;    protected decimal QuickDeduction = 0;    public virtual decimal Calculate(decimal income) {        return income * TaxRate - QuickDeduction;    }}

策略基類Tax,表示個人所得稅,TaxRate為稅率,QuickDeduction為速算扣除數,Calculate計算相應收入的個人所得稅。

public class Level0 : Tax {    public Level0() {        TaxRate = 0.00m;        QuickDeduction = 0;    }}

0級個人所得稅階梯,表示個人所得稅的初始狀態。

public class Level1 : Tax {    public Level1() {        TaxRate = 0.03m;        QuickDeduction = 0;    }}

1級個人所得稅階梯。

public class Level2 : Tax {    public Level2() {        TaxRate = 0.10m;        QuickDeduction = 105;    }}

2級個人所得稅階梯。

public class Level3 : Tax {    public Level3() {        TaxRate = 0.20m;        QuickDeduction = 555;    }}

3級個人所得稅階梯。

public class Level4 : Tax {    public Level4() {        TaxRate = 0.25m;        QuickDeduction = 1005;    }}

4級個人所得稅階梯。

public class Level5 : Tax {    public Level5() {        TaxRate = 0.30m;        QuickDeduction = 2755;    }}

5級個人所得稅階梯。

public class Level6 : Tax {    public Level6() {        TaxRate = 0.35m;        QuickDeduction = 5505;    }}

6級個人所得稅階梯。

public class Level7 : Tax {    public Level7() {        TaxRate = 0.45m;        QuickDeduction = 13505;    }}

7級個人所得稅階梯。

public class Context {    private Tax _tax = null;    private const decimal EXEMPTION_VALUE = 3500m;    private List<decimal> _taxLevel = new List<decimal>{        0,        1500,        4500,        9000,        35000,        55000,        80000,        decimal.MaxValue    };    private List<Type> _levels = new List<Type>();    private void GetLevels() {        _levels = AppDomain.CurrentDomain.GetAssemblies()                           .SelectMany(tp => tp.GetTypes()                           .Where(t => t.BaseType == typeof(Tax)))                           .ToList();    }    public Context() {        GetLevels();    }    public Context Calculate(decimal income) {        _tax = new Level0();        var result = income - EXEMPTION_VALUE;        for(int i = 1; i <= _taxLevel.Count - 1; i++) {            if(result > _taxLevel[i - 1] && result <= _taxLevel[i]) {                _tax = (Tax)Activator.CreateInstance(_levels[i]);            }        }        Console.WriteLine($"Income = {income}," + $"tax = {_tax.Calculate(result)}!");        return this;    }}

環境類Context,首先需要維持對Tax的引用,EXEMPTION_VALUE表示免徵額(本例使用3500元),之後通過反射和一些技巧選擇相應的Tax實作類別來計算相應階梯的個人所得稅。

public class Program {    private static Context _context = new Context();    public static void Main(string[] args) {        _context.Calculate(2500.00m)                .Calculate(4900.00m)                .Calculate(5500.00m)                .Calculate(7000.00m)                .Calculate(10000.00m)                .Calculate(16000.00m)                .Calculate(43000.00m)                .Calculate(70000.00m)                .Calculate(100000.00m)                .Calculate(4500.00m)                .Calculate(1986.00m);        Console.ReadKey();    }}

以上是調用方的代碼,Calculate經過特殊處理以支援方法鏈。以下是這個案例的輸出結果:

Income = 2500.00,tax = 0.0000!Income = 4900.00,tax = 42.0000!Income = 5500.00,tax = 95.0000!Income = 7000.00,tax = 245.0000!Income = 10000.00,tax = 745.0000!Income = 16000.00,tax = 2120.0000!Income = 43000.00,tax = 9095.0000!Income = 70000.00,tax = 17770.0000!Income = 100000.00,tax = 29920.0000!Income = 4500.00,tax = 30.0000!Income = 1986.00,tax = 0.0000!

優點:

1、策略類的等級結構定義了一個演算法或行為族,恰當使用繼承可以把公用的代碼移到父類裡面,從而避免重複的代碼;
2、繼承可以處理多種演算法或行為,可以避免使用多重條件轉移語句。

缺點:

1、用戶端必須知道所有的策略類,並自行決定使用哪一個策略類;
2、策略模式造成很多的策略類,造成“子類爆炸”。

使用情境:

1、如果在一個系統裡面有許多類,它們之間的區別僅在於它們的行為,那麼使用原則模式可以動態地讓一個對象在許多行為中選擇一種行為;
2、一個系統需要動態地在幾種演算法中選擇一種。

相關文章:

使用C/C++編寫PHP Extension

【c#教程】C# 資料類型

相關視頻:

什麼是設計模式-php進階設計模式視頻教程

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.