C# дизайн класса, гибкие правила оплаты

В настоящее время я моделирую систему, отвечающую за управление выплатами роялти. Роялти может быть таким простым:

  • Оплатить автора A 15% дохода

или такой сложный как:

  • Оплатить автора Б 15% от выручки до 1000 проданных товаров, затем 12% от выручки
  • Также заплатите автору B $1,50 за каждую проданную до 1000 проданную сумму

или же:

  • Оплатить автора C 15% от дохода за первый доход в 1000 долларов, затем 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 ответа

Ознакомьтесь с шаблоном спецификации - эта банка со сложной спецификацией правил - именно то, для чего она предназначена.

В компьютерном программировании шаблон спецификации является конкретным шаблоном проектирования программного обеспечения, в котором бизнес-правила могут быть объединены путем объединения бизнес-правил вместе с использованием логической логики.

Шаблон спецификации описывает бизнес-правило, которое можно комбинировать с другими бизнес-правилами. В этом шаблоне единица бизнес-логики наследует свои функциональные возможности от абстрактного совокупного класса составной спецификации. Класс составной спецификации имеет одну функцию с именем IsSatisfiedBy, которая возвращает логическое значение. После реализации спецификация "сцепляется" с другими спецификациями, что делает новые спецификации легко поддерживаемыми, но в то же время легко настраиваемой бизнес-логикой. Кроме того, при создании экземпляра бизнес-логика может посредством изменения метода или обращения к управлению изменить свое состояние, чтобы стать делегатом других классов, таких как постоянное хранилище.

Я бы попытался создать какой-то плавный интерфейс, объединяющий методы расширения, выражения linq, подбор методов и именованные аргументы, возможно, что-то вроде этого:

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);
Другие вопросы по тегам