首页 > 编程语言 >C#接口的简单应用

C#接口的简单应用

时间:2022-12-23 23:57:00浏览次数:40  
标签:set get C# 接口 public 订单 应用 order freightCalculator

场景说明

现在有一个订单处理系统,需要我们调整计算价格(价格=产品总价+运费)中“计算运费”的逻辑:

  1. 在双11的时候,无论订单的金额多少钱,都可以免邮费;
  2. 在正常情况下订单的金额超过88元时就可以免邮,如果不到88元就需要付12元的快递费。

源代码

namespace _6_3_end
{
    public class Program
    {
        static void Main(string[] args)
        {
            Order order = new Order
            {
                Id = 100200,
                OrderData = DateTime.Now,
                TotalProductPrice = 300,
                HasDelivery = false,
            };
            OrderProcessor orderProcessor = new OrderProcessor();
            orderProcessor.Process(order);

            Console.Read();
        }
    }
    /// <summary>
    /// 订单
    /// </summary>
    public class Order
    {
        public int Id { get; set; }
        public DateTime OrderData { get; set; }
        public decimal TotalProductPrice { get; set; }
        public bool HasDelivery { get; set; }//是否发货
        public Freight Freight { get; set; }//运费
    }
    /// <summary>
    /// 运费
    /// </summary>
    public class Freight
    {
        public decimal Cost { get; set; }
        public DateTime DeliveryDate { get; set; }
    }
    /// <summary>
    /// 运费计算
    /// </summary>
    public class FreightCalculator
    {
        public decimal CalculateFreight(Order order)
        {
            if (order.TotalProductPrice <= 88)
            {
                return 12;
            }
            return 0;
        }
    }
    /// <summary>
    /// 订单处理
    /// 专门用来处理订单,我们会在这里计算订单的运费、改变订单的状态。
    /// 比如说,订单总金额超过88块,我们就可以给这个用户免运费,否则每次出货都要收取12块钱的运费
    /// </summary>
    public class OrderProcessor
    {
        private readonly FreightCalculator _freightCalculator;
        public OrderProcessor()
        {
            _freightCalculator = new FreightCalculator();
        }
        public void Process(Order order)
        {
            if (order.HasDelivery)
            {
                throw new InvalidOperationException("订单已发货");
            }

            order.Freight = new Freight
            {
                Cost = _freightCalculator.CalculateFreight(order),
                DeliveryDate = DateTime.Today.AddDays(1)
            };
            order.TotalProductPrice = order.TotalProductPrice + _freightCalculator.CalculateFreight(order);
            Console.WriteLine($"订单:{order.Id}已处理完成,总价格为{order.TotalProductPrice}元");
        }
    }
}

UML

这幅图中两个类的关系,这是订单处理系统和价格计算系统之间的UML关系图

从图中我们可以看到这两个系统之间的依赖关系是has-a的关系。订单处理系统有一个价格计算系统。如果计算价格方式发生了变化,那么它一定会影响到订单系统,而订单的变化可以又会反应给其他的系统,造成全局性的改变。所以说,订单系统和价格系统目前是一种紧耦合的状态。所以,对于这种has-a的关系,我们可以选择使用接口来给两个系统解耦。
所以UML中的关系可以改成这样:

使用价格接口来替换价格系统。这样订单系统则会从依赖于一个类转换为依赖于一个接口,而接口的定义,它就是一个简单的声明,不是完整的Class,不包含任何业务逻辑,他的方法也没有代码实现。
至于价格接口的实现,我们完全可以放在一个独立的class中去处理,比如说双十一价格系统、618价格系统、普通价格系统等等,而订单系统可以通过接口来间接使用价格计算的代码实现。
如果未来价格的计算发生了改变,我们只需要在保持价格接口不变的前提下,对现有的实现逻辑进行修改就可以了。我们甚至可以直接给接口换一个新的Class重写实现都没有问题。
对订单来说价格根本就是个黑盒子,订单系统只需要知道什么时候调用价格计算方法就可以了!所以说计算价格的时候调用的底层逻辑是来自Class A 还是 Class B,对于订单来说都不重要,它不知道、也不需要知道计算价格的过程。
所以,通过接口,我们便可以顺利的使订单系统和价格系统形成松耦合的状态。

使用接口改进源代码

  1. FreightCalculatorclass抽离出来作为一个接口:IFreightCalculatorclass
  2. 修改OrderProcessorclass,将原来价格计算变量修改为IFreightCalculator
  3. 修改FreightCalculatorclass:(1)继承IFreightCalculator (2)实现IFreightCalculator ,修改完成后作为正常情况下计算邮费的逻辑
  4. 添加DoubleElevenFreightCalculatorclass,(1)继承IFreightCalculator (2)实现IFreightCalculator ,可以在双11的情况下使用
  5. 修改main方法
namespace _6_3_end
{
    public class Program
    {
        static void Main(string[] args)
        {
            Order order = new Order
            {
                Id = 100200,
                OrderData = DateTime.Now,
                TotalProductPrice = 20,
                HasDelivery = false,
            };
            DoubleElevenFreightCalculator doubleEleven = new DoubleElevenFreightCalculator();
            OrderProcessor orderProcessor = new OrderProcessor(doubleEleven);
            orderProcessor.Process(order);

            Console.Read();
        }
    }
    /// <summary>
    /// 订单
    /// </summary>
    public class Order
    {
        public int Id { get; set; }
        public DateTime OrderData { get; set; }
        public decimal TotalProductPrice { get; set; }
        public bool HasDelivery { get; set; }//是否发货
        public Freight Freight { get; set; }//运费
    }
    /// <summary>
    /// 运费
    /// </summary>
    public class Freight
    {
        public decimal Cost { get; set; }
        public DateTime DeliveryDate { get; set; }
    }
    /// <summary>
    /// 运费计算(正常情况)
    /// </summary>
    public class FreightCalculator : IFreightCalculator
    {
        public decimal CalculateFreight(Order order)
        {
            if (order.TotalProductPrice <= 88)
            {
                return 12;
            }
            return 0;
        }
    }
    /// <summary>
    /// 订单处理
    /// 专门用来处理订单,我们会在这里计算订单的运费、改变订单的状态。
    /// 比如说,订单总金额超过88块,我们就可以给这个用户免运费,否则每次出货都要收取12块钱的运费
    /// </summary>
    public class OrderProcessor
    {
        //private readonly FreightCalculator _freightCalculator;
        private readonly IFreightCalculator _freightCalculator;
        //public OrderProcessor()
        //{
        //    _freightCalculator = new FreightCalculator();
        //}
        public OrderProcessor(IFreightCalculator freightCalculator)
        {
            _freightCalculator = freightCalculator;
        }
        public void Process(Order order)
        {
            if (order.HasDelivery)
            {
                throw new InvalidOperationException("订单已发货");
            }

            order.Freight = new Freight
            {
                Cost = _freightCalculator.CalculateFreight(order),
                DeliveryDate = DateTime.Today.AddDays(1)
            };
            order.TotalProductPrice = order.TotalProductPrice + _freightCalculator.CalculateFreight(order);
            Console.WriteLine($"订单:{order.Id}已处理完成,总价格为{order.TotalProductPrice}元");
        }
    }

    public interface IFreightCalculator
    {
        public decimal CalculateFreight(Order order);
    }
    /// <summary>
    /// 运费计算(双11)
    /// </summary>
    public class DoubleElevenFreightCalculator : IFreightCalculator
    {
        public decimal CalculateFreight(Order order)
        {
            //在双11的时候,无论订单的金额多少钱,都可以免邮费
            return 0;
        }
    }
}

标签:set,get,C#,接口,public,订单,应用,order,freightCalculator
From: https://www.cnblogs.com/ynysj/p/17000476.html

相关文章