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