Классы без логики: запах кода или уродливый системный факт?

Я работаю над приложением, которое частично вычисляет суммы налоговых платежей. Налоговый счет состоит из множества вычисляемых полей (гонорары шерифа, гонорары клерка, штрафы, проценты, фиксированные ставки и т. д.), способ расчета которых обычно статичен, но может меняться в соответствии с законодательством или специальным счетом. характеристики. Целые категории расчетов также могут быть удалены или добавлены с течением времени.

Чтобы убрать от клиента беспорядок логики ветвления, я написал фабрику для каждой категории вычислений, которая будет применять правильные вычисления с учетом информации о счете, например так (CalcType — это перечисление):

var bill = new Bill(){year = 2013};
bill.AdvertisingFee = CalculationFactory.GetFee(CalcType.AdvFee, bill);

Это очень просто, но меня беспокоит то, как будут реализованы некоторые из моих конкретных классов. Вот интерфейс расчета:

public interface ITaxCalculation{
    decimal Calculate();
}

Типичная реализация будет иметь какие-то вычисления или доступ к данным, но определенные свойства year/bill не приносят платы за рекламу, например:

public class FinanceCabinetAdvertisingFee : ITaxCalculation
{
    public decimal Calculate()
    {
        return 0.00M;
    }
}

Этот класс-заглушка будет присутствовать для многих, но не для всех категорий расчетов по разным причинам (расчет не существовал для налогового года, государство купило счет и т. д.).

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


person abarger    schedule 21.02.2014    source источник
comment
Они лишены логики? Я бы сказал, что нулевая плата — это тоже логика. Добавление свойства YieldsFee ничего не добавит, если только вы не хотите отличить нулевую комиссию от отсутствия комиссии. Но даже в этом случае можно вернуть decimal?.   -  person C.Evenhuis    schedule 22.02.2014
comment
@FolksymAndrew Я бы определенно сказал, что есть большая разница между тем, чтобы платить 0.00, и тем, чтобы вообще не платить. В таких случаях я предпочитаю использовать обнуляемые значения, а не такие, может быть, очевидные соглашения, как платить 0.00 то же самое, что не платить. В какой-то момент вам действительно может понадобиться отличать те случаи, которые действительно были бесплатными, от тех, которые говорят - уже заплатили и в настоящее время они должны платить 0.00, но это потому, что они уже заплатили.   -  person Leron_says_get_back_Monica    schedule 22.02.2014
comment
@Leron, это хорошие моменты. Узнав, что в IEnumerable есть метод Sum для нулевых значений, я понял, что простой возврат нулей для случаев, когда плата не существует, не будет болезненным или неуклюжим в обработке. Тем не менее, это все еще оставляет вопрос: предпочтительнее ли изменить мой класс FinanceCabinetAdvertisingFee, чтобы Calculate() возвращал null как форму положительной документации, или позволить фабрике возвращать null и позволить несуществованию класса служить в качестве документации?   -  person abarger    schedule 23.02.2014
comment
@FolksymAndrew Ну, на твоем месте я бы поменял оба. Но я думаю, что лучше выслушать хотя бы еще несколько мнений. Каждый раз, когда вы оставляете что-то само собой разумеющимся, вы оставляете возможность кому-то неверно истолковать вашу логику.   -  person Leron_says_get_back_Monica    schedule 23.02.2014
comment
@C.Evenhuis Я согласен с тем, что, возможно, стоит отделить 0 комиссий от нулевых, и это действительно зависит от спецификаций. Тем не менее, я бы предложил сделать это с помощью подхода Nullable‹›, то есть decimal? Fee(), так как это сделает его более явным и менее подверженным ошибкам кодирования, когда кто-то забывает проверить значение YieldsFee перед проверкой Fee.   -  person LB2    schedule 25.02.2014


Ответы (1)


Я бы поместил такие магические значения в базу данных или файл конфигурации, возможно, зашифровав их, если вы хотите скрыть их от пользователей. Тогда этот класс будет классом доступа к данным, и будет проще и более модульно обновлять значения, когда вам это нужно.

Жесткое кодирование данных в коде иногда необходимо, но, вероятно, это не оптимально для этого.

person Adam Miller    schedule 21.02.2014