理解:策略就是平常设计模式中所说的策略模式。因为当你有一个庞大的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 }