第11天:用策略模式代替switch
今天的重构很有意思,旧的代码是根据参数State来调用三个不同的方法,获取三个地方的装运量
代码如下:

public class ClientCode
{
public decimal CalculateShipping()
{
ShippingInfo shippingInfo = new ShippingInfo();
return shippingInfo.CalculateShippingAmount(State.Alaska);
}
}
public enum State
{
Alaska,
NewYork,
Florida
}
public class ShippingInfo
{
public decimal CalculateShippingAmount(State shipToState)
{
switch (shipToState)
{
case State.Alaska:
return GetAlaskaShippingAmount();
case State.NewYork:
return GetNewYorkShippingAmount();
case State.Florida:
return GetFloridaShippingAmount();
default:
return 0m;
}
}
private decimal GetAlaskaShippingAmount()
{
return 15m;
}
private decimal GetNewYorkShippingAmount()
{
return 10m;
}
private decimal GetFloridaShippingAmount()
{
return 3m;
}
}
如果我们现在要加一个Chicago的条件,那么不得不修改整个ShippingInfo
重构后用策略模式,对每一个条件加一个类,并且实现同一个接口,以后如果希望添加新的条件,只需添加新的实现类就可以了,实现对修改关闭,对扩展开放
重构后的代码如下

public class ClientCode
{
public decimal CalculateShipping()
{
ShippingInfo shippingInfo = new ShippingInfo();
return shippingInfo.CalculateShippingAmount(State.Alaska);
}
}
public enum State
{
Alaska,
NewYork,
Florida
}
public class ShippingInfo
{
private IDictionary<State, IShippingCalculation> ShippingCalculations
{ get; set; }
public ShippingInfo()
{
ShippingCalculations = new Dictionary<State, IShippingCalculation>{
{ State.Alaska, new AlaskShippingCalculation() },
{ State.NewYork, new NewYorkShippingCalculation() },
{ State.Florida, new FloridaShippingCalculation() }};
}
public decimal CalculateShippingAmount(State shipToState)
{
return ShippingCalculations[shipToState].Calculate();
}
}
public interface IShippingCalculation
{
decimal Calculate();
}
public class AlaskShippingCalculation : IShippingCalculation
{
public decimal Calculate()
{
return 15m;
}
}
public class NewYorkShippingCalculation : IShippingCalculation
{
public decimal Calculate()
{
return 10m;
}
}
public class FloridaShippingCalculation : IShippingCalculation
{
public decimal Calculate()
{
return 3m;
}
}
故事还没完,书的作者又进行了如下的重构,今天没有弄明白,先记录下来

public interface IShippingInfo
{
decimal CalculateShippingAmount(State state);
}
public class ClientCode
{
[Inject]
public IShippingInfo ShippingInfo { get; set; }
public decimal CalculateShipping()
{
return ShippingInfo.CalculateShippingAmount(State.Alaska);
}
}
public enum State
{
Alaska,
NewYork,
Florida
}
public class ShippingInfo : IShippingInfo
{
private IDictionary<State, IShippingCalculation> ShippingCalculations
{ get; set; }
public ShippingInfo(IEnumerable<IShippingCalculation> shippingCalculations)
{
ShippingCalculations = shippingCalculations.ToDictionary(
calc => calc.State);
}
public decimal CalculateShippingAmount(State shipToState)
{
return ShippingCalculations[shipToState].Calculate();
}
}
public interface IShippingCalculation
{
State State { get; }
decimal Calculate();
}
public class AlaskShippingCalculation : IShippingCalculation
{
public State State { get { return State.Alaska; } }
public decimal Calculate()
{
return 15m;
}
}
public class NewYorkShippingCalculation : IShippingCalculation
{
public State State { get { return State.NewYork; } }
public decimal Calculate()
{
return 10m;
}
}
public class FloridaShippingCalculation : IShippingCalculation
{
public State State { get { return State.Florida; } }
public decimal Calculate()
{
return 3m;
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)
2021-03-10 docker构建镜像
2021-03-10 [C#]LINQ中如何按实体的某个属性去重
2021-03-10 .NET Core项目部署到Linux(Centos7)(九)防火墙配置,允许外网或局域网访问.NET Core站点
2021-03-10 c++ 手动加载 netcore_在基于Debian开发的Deepin上快速搭建.net core开发环境
2021-03-10 git的基本使用流程演示
2021-03-10 .NET5都来了,你还不知道怎么部署到linux?最全部署方案,总有一款适合你
2021-03-10 DotNetCore深入了解:HTTPClientFactory类