繁体   English   中英

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

[英]Design pattern / Architecture for different charge types for a customer

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

有多种充电类型,每种充电类型包括不同的充电项目。

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

    //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(),具体取决于我调用的Calculate方法,我该如何实现?

我打算为每种电荷类型创建不同的电荷类型参数类,然后确定电荷类型并使用一些if else语句调用Calculate函数传递相关参数类型,但我认为这不是一个好主意。 有没有更好的方法来实现这一目标,还是有另一种完全不同的方式来实现我在这里尝试做的事情?

谢谢

这取决于。 有很多方法可以实现这一点,选择一个将取决于你可以轻松分享的更多背景。 这里有一些想法:

  • 创建一个CalculateParams类型来保存所有各种参数,仅在seome位置使用它们。
  • 在构造时将此信息放入ChargeItem
  • 创建一个负责这两条信息的ChargeCalculator
  • 等等...

你遇到这个问题的原因是你正试图从“中间”出来构建。 获得所需抽象的一个好方法是编写依赖于这些抽象的类的代码和测试。 现场发明基于您正在编写的测试和生产代码的需求的方法,而不是猜测那些抽象应该是什么样的。 这是使您能够创建基于需求的抽象的最佳方式,顾名思义,它可以最好地满足您的需求。

将@Ryan Bennett的评论从上面扩展到我认为你可以做的事情。

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

正如你上面的评论中提到将被注入Calculator上的Calculate()方法而定。 抽象的Calculate()方法(of ChargeItem )的实现只关心Calculator接口。

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

希望这可以帮助。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM