第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;
        }
    }
 
复制代码
转 https://www.cnblogs.com/ysuhy/archive/2010/01/04/1639123.html
posted @   dreamw  阅读(69)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享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类
点击右上角即可分享
微信分享提示