c# - 针对客户不同收费类型的设计模式/架构

标签 c# oop design-patterns factory-pattern

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

收费类型有多种,每种收费类型包含不同的收费项目。

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

    //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);
            }               
        }

我需要能够根据调用的 Calculate 方法从 foreach 循环内将不同类型的参数传递给 chargeItem.Calculate(),我该如何实现?

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

谢谢

最佳答案

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

  • 创建一个 CalculateParams 类型来保存所有不同的参数, 只在某些地方使用它们。
  • 在构造时将此信息放入 ChargeItem
  • 创建一个负责这两条信息的 ChargeCalculator
  • 等...

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

关于c# - 针对客户不同收费类型的设计模式/架构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14526407/

相关文章:

Javascript 类,事件监听器中的 var 未定义

c# - 如何在没有 yield 语句的情况下实现迭代器模式 (IEnumerator<T>)

php - 我应该在哪里创建对象?存储库?工厂?

c# - 代理/ socks C# 问题

php - 如何使用函数名和参数作为变量来调用适当的函数? PHP

c# - 在曲线路径上绘制形状或图像

php - MySQL PDO - 设置默认获取模式?

design-patterns - 织物 JS 中对象缩放的模式重复

c# - 使用LINQ根据Where过滤List中的某个值

c# - C# 中的二进制序列化(实际上是所见即所得序列化)