C#类设计,灵活的支付规则

时间:2012-05-09 20:07:11

标签: c# single-responsibility-principle

我目前正在建立一个负责管理特许权使用费付款的系统。特许权使用费可能很简单:

  • 支付作者15%的收入

或与以下任何一个一样复杂:

  • 支付作者B 15%的收入,最多1000个销售量,然后12%的收入
  • 还支付作者B $ 1.50,每售出1000件,销售数量

或:

  • 向作者C支付前1000美元收入的15%收入,然后是收入的12%

简而言之,付款可能是每个销售的固定金额或收入的百分比。付款条件可以基于销售数量或收入。我试图通过指定付款范围和付款值的类型来设计一个类(与幕后的数据库表紧密对应),其中包含所有这些灵活性。但是,我担心我可能会尝试让这堂课做得太多,如果我们将来需要适应其他场景,可能会支持自己。我正在寻求替代设计方法的建议。

public class PaymentRule
{
    // I'm not 100% comfortable with this, as this will
    // really be an Int32 value for quantity sold ranges
    public decimal RangeMinimum { get; set; }
    public decimal? RangeMaximum { get; set; }

    // This will always be a decimal value, but may represent
    // a dollar amount or percentage depending on the context
    public decimal PaymentValue { get; set; }

    // Specify a type for the range: QuantitySold or Revenue
    public string RangeType { get; set; }

    // Specify a type for the value: AmountPerEachSold or RevenuePercentage
    public decimal ValueType { get; set; }

    public decimal CalculateRoyaltyDue(int quantitySold, decimal revenue)
    {
        // ...
    }
}

任何建议都将不胜感激。

更新5/9/2012:

我应该提到这些规则必须保存到SQL Server数据库。

2 个答案:

答案 0 :(得分:1)

查看specification pattern - 这个复杂的规则规范就是它的设计目的。

  

在计算机编程中,规范模式是一种特定的软件设计模式,通过使用布尔逻辑将业务规则链接在一起,可以重新组合业务规则。

     

规范模式概述了可与其他业务规则组合的业务规则。在此模式中,业务逻辑单元从抽象聚合Composite Specification类继承其功能。 Composite Specification类有一个名为IsSatisfiedBy的函数,它返回一个布尔值。实例化后,规范与其他规范“链接”,使新规范易于维护,但高度可定制的业务逻辑。此外,在实例化时,业务逻辑可以通过方法调用或控制反转来更改其状态,以便成为其他类(如持久性存储库)的委托。

答案 1 :(得分:-1)

我会尝试构建一些结合扩展方法,linq表达式,方法chining和命名参数的流畅接口,可能是这样的:

var revenue = 12000;
var ruleA = Rules.PayAuthor(15).PercentOf(revenue)
var ruleB = Rules.PayAuthor(15).PercentOf(revenue).UpTo(soldUnits:1000).Then(12).PercentOf(revenue)

var royalltyA = Royallty.For(ruleA, whenSoldUnitsIs: 1500);
var royalltyB = Royallty.For(ruleB, whenSoldUnitsIs: 1500);