为客户的不同收费类型设计模式/架构

本文关键字:类型 设计模式 架构 客户 | 更新日期: 2023-09-27 17:55:56

我们有一个系统,用于向客户收取不同类型的费用。

有多种费用类型

,每种费用类型包括不同的费用项目。

以下是我使用工厂方法提出的方法,这个问题是我需要能够根据电荷类型将不同的参数传递给每个计算函数,我该如何实现?

    //product abstract class
    public abstract class ChargeItem
    {
        public abstract List<ChargeResults> Calculate();
    }
    //Concrete product classes
    public class ChargeType1 : ChargeItem
    {
        public override List<ChargeResults> Calculate()
        {
            return new List<ChargeResults> { new ChargeResults { CustomerId = 1, ChargeTotal = 10} };
        }
    }
    public class ChargeType2 : ChargeItem
    {
        public override List<ChargeResults> Calculate()
        {
            return new List<ChargeResults> { new ChargeResults { CustomerId = 2, ChargeTotal = 20} };
        }
    }
    public class ChargeType3 : ChargeItem
    {
        public override List<ChargeResults> Calculate()
        {
            return new List<ChargeResults> { new ChargeResults { CustomerId = 3, ChargeTotal = 30} };
        }
    }
    //Creator abstract class
    public abstract class GeneralCustomerCharge
    {
        //default constructor invokes the factory class
        protected GeneralCustomerCharge()
        {
            this.CreateCharges();
        }
        public List<ChargeItem> ChargeItems { get; protected set; }
        public abstract void CreateCharges();
    }
    public class AssetCharges : GeneralCustomerCharge
    {
        public override void CreateCharges()
        {
            ChargeItems = new List<ChargeItem> { new ChargeType1(), new ChargeType2() };
        }
    }
    public class SubscriptionCharges : GeneralCustomerCharge
    {
        public override void CreateCharges()
        {
            ChargeItems = new List<ChargeItem> { new ChargeType3() };
        }
    }
    public class ChargeResults
    {
        public int CustomerId { get; set; }
        public decimal ChargeTotal { get; set; }
    }

用法是:

        var newAssetCharge = new AssetCharges();
        foreach (ChargeItem chargeItem in newAssetCharge.ChargeItems)
        {
            foreach (var item in chargeItem.Calculate())
            {
                Console.WriteLine("Asset Charges For Customer Id: {0}, Charge Total:     {1}", item.CustomerId, item.ChargeTotal);
            }               
        }

我需要能够将不同类型的参数从foreach循环中传递给chargeItem.Calculate(),具体取决于我调用的计算方法,我该如何实现这一点?

我计划为每个电荷类型创建不同的电荷类型参数类,然后确定电荷类型并使用一些 if else 语句调用传递相关参数类型的 Compute 函数,但我认为这不是一个好主意。有没有更好的方法来做到这一点,或者有另一种完全不同的方法来实现我在这里想要做的事情?

谢谢

为客户的不同收费类型设计模式/架构

这取决于。 将有很多方法可以实现这一点,选择一种将取决于更多的上下文,而不是您在此处轻松共享的上下文。 这里有一些想法:

  • 创建一个CalculateParams类型来保存所有各种参数,仅在西梅的地方使用它们。
  • 将此信息放入施工时的ChargeItem中。
  • 创建一个负责这两个信息的收费计算器
  • 等。。。

遇到此问题的原因是您正在尝试从"中间"进行架构。 获取所需抽象的一个好方法是为依赖于这些抽象的类编写代码和测试。 当场发明基于您正在编写的测试和生产代码需求的方法,而不是猜测这些抽象应该是什么样子。 这是使您能够创建基于需求的抽象的最佳方式,顾名思义,这些抽象往往最能满足您的需求。

扩展上面@Ryan贝内特的评论,这是我认为你可以做的。

  1. 使用 PerformCalculation() 方法创建Calculator接口。
  2. 使用返回相应Calculator实现的 GenerateCalculator() 方法创建一个 CalculatorFactory 类。工厂根据传递给 GenerateCalculator() 方法的参数(if/else 语句)构造Calculator实现对象。
  3. 将生成的Calculator实现传递到抽象Calculate()方法中。

如上面的注释中所述,您将注入Calculate()方法所依赖的Calculator。抽象Calculate()方法(ChargeItem)的实现只关心Calculator接口。

Calculator的单独实现将确保计算根据您的规则以不同的方式进行。

希望这有帮助。