重构第11天 使用策略代替Switch(Switch to Strategy)

理解:策略就是平常设计模式中所说的策略模式。因为当你有一个庞大的switch方法的时候,每一次新加一个条件,都要去修改这个方法,这样耦合性太高,不易维护也不易扩展。这样我们就可以使用策略的设计模式,使得每一种情况都封装在自己的类中,来提高扩展性和降低耦合性。

详解

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 
 6 namespace _31DaysRefactor
 7 {
 8 
 9     public class ClientCode
10     {
11 
12         public decimal CalculateShipping()
13         {
14             ShippingInfo shippinginfo = new ShippingInfo();
15 
16             return shippinginfo.CalclateShippingAmount(State.Alaska);
17         }
18 
19     }
20 
21 
22     public enum State
23     {
24         Alaska,
25         NewYork,
26         Florida
27     }
28 
29     public class ShippingInfo
30     {
31 
32         public decimal CalclateShippingAmount(State shipToState)
33         {
34             switch (shipToState)
35             {
36                 case State.Alaska:
37                     return GetAlaskaShippingAmount();
38                 case State.NewYork:
39                     return GetNewYorkShippingAmount();
40                 case State.Florida:
41                     return GetFloridaShippingAmount();
42                 default:
43                     return 0m;
44             }
45         }
46 
47         private decimal GetAlaskaShippingAmount()
48         {
49             return 15m;
50         }
51 
52         private decimal GetNewYorkShippingAmount()
53         {
54             return 10m;
55         }
56 
57         private decimal GetFloridaShippingAmount()
58         {
59             return 3m;
60         }
61     }
62 }

为了完成switch重构,我们需要把每一种条件封装成一个独立的类,然后这些类提取出一个公共接口,每个类都实现该接口。下次如果你想添加新的条件,只需要新增一个实现该公共接口的类即可。

这里我们提取出一个公共接口IShippingCalculation,这个类包含一个方法decimal Caculate()和一个属性 State State { get; }。

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 
 6 namespace _31DaysRefactor
 7 {
 8 
 9     public class ClientCode
10     {
11 
12         public decimal CalculateShipping()
13         {
14             IShippingInfo shippingInfo = new ShippingInfo();
15             return shippingInfo.CalculateShippingAmount(State.Alaska);
16         }
17 
18     }
19 
20 
21     public enum State
22     {
23         Alaska,
24         NewYork,
25         Florida
26     }
27 
28 
29     public interface IShippingCalculation
30     {
31         decimal Caculate();
32     }
33 
34     public interface IShippingInfo
35     {
36         decimal CalculateShippingAmount(State state);
37     }
38 
39     public class ShippingInfo : IShippingInfo
40     {
41         private IDictionary<State, IShippingCalculation> ShippingCalculations { get; set; }
42 
43         public ShippingInfo()
44         {
45             ShippingCalculations = new Dictionary<State, IShippingCalculation>(){
46                 {State.Alaska,new AlaskShippingCaculation()},
47                 {State.Florida,new FloridaShippingCaculation()},
48                 {State.NewYork,new NewYorkShippingCaculation()}
49             };
50         }
51 
52         public decimal CalculateShippingAmount(State shipToState)
53         {
54             return this.ShippingCalculations[shipToState].Caculate();
55         }
56 
57     }
58 
59 
60     public class AlaskShippingCaculation : IShippingCalculation
61     {
62         public State State { get { return State.Alaska; } }
63 
64         public decimal Caculate()
65         {
66             return 15m;
67         }
68     }
69 
70 
71     public class NewYorkShippingCaculation : IShippingCalculation
72     {
73         public State State { get { return State.NewYork; } }
74 
75         public decimal Caculate()
76         {
77             return 10m;
78         }
79     }
80 
81 
82     public class FloridaShippingCaculation : IShippingCalculation
83     {
84         public State State { get { return State.Florida; } }
85 
86         public decimal Caculate()
87         {
88             return 3m;
89         }
90     }
91 }
原文地址:https://www.cnblogs.com/yplong/p/5308648.html