天天看點

【愚公系列】2021年12月 二十三種設計模式(二十一)-政策模式(Stragety Pattern)

文章目錄

前言

一、政策模式(Stragety Pattern)

二、使用步驟

角色

示例

總結

優點

缺點

使用場景

提示:這裡可以添加本文要記錄的大概内容:

例如:随着人工智能的不斷發展,機器學習這門技術也越來越重要,很多人都開啟了學習機器學習,本文就介紹了機器學習的基礎内容。

提示:以下是本篇文章正文内容,下面案例可供參考

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

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

1、抽象政策(Strategy)

這是一個抽象角色,通常由一個接口或抽象類實作。此角色給出所有的具體政策類所需的接口;

2、具體政策(Concrete Strategy)

實作抽象政策的具體政策類,包裝了相關的算法或行為;

3、環境類(Context)

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

【愚公系列】2021年12月 二十三種設計模式(二十一)-政策模式(Stragety Pattern)
命名空間StragetyPattern中包含政策基類Tax以及它的8個實作類,Context環境類持有政策基類。本示例通過一個優雅的方式來計算個人所得稅。

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、一個系統需要動态地在幾種算法中選擇一種。

繼續閱讀