Логический код проверки бизнеса Запах

Рассмотрим следующий код:

partial class OurBusinessObject {
    partial void OnOurPropertyChanged() {
        if(ValidateOurProperty(this.OurProperty) == false) {
            this.OurProperty = OurBusinessObject.Default.OurProperty;
        }
    }
}

То есть, когда значение OurProperty в OurBusinessObject изменяется, если значение недопустимо, установите его значение по умолчанию. Этот шаблон поражает меня как запах кода, но другие здесь (у моего работодателя) не согласны. Каковы ваши мысли?

Отредактировано для добавления: меня попросили добавить объяснение, почему это считается приемлемым. Идея заключалась в том, что вместо того, чтобы производители бизнес-объекта проверяли данные, бизнес-объект мог проверять свои собственные свойства и устанавливать чистые значения по умолчанию в случаях, когда проверка не удалась. Кроме того, считалось, что если правила проверки изменятся, разработчикам бизнес-объектов не придется менять свою логику, поскольку бизнес-объект будет заботиться о проверке и очистке данных.

Ответ 1

Это абсолютно ужасно. Удачи, пытаясь отладить проблемы в Production. Единственное, что это может привести, это обложка ошибок, которые будут просто появляться где-то в другом месте, где они не будут очевидны вообще, откуда они пришли.

Ответ 2

Думаю, я должен согласиться с тобой. Это может определенно привести к проблемам, когда логика неожиданно возвращается к значениям по умолчанию, что может быть очень сложно отладить.

По крайней мере, это поведение должно регистрироваться, но это больше похоже на случай исключения исключений.

Ответ 3

Для меня это похоже на симптом, а не на фактическую проблему. Что действительно происходит, так это то, что установщик для OurProperty не сохраняет исходное значение для использования в событии OnOurPropertyChanged. Если вы это сделаете, вам станет легче выбирать, как действовать дальше.

В этом случае то, что вы действительно хотите, - это событие OnOurPropertyChanging, которое возникает из сеттера до того, как действительно выполняется присвоение. Таким образом, вы можете разрешить или опровергнуть назначение в первую очередь. В противном случае существует небольшой промежуток времени, когда ваш объект недействителен, и это означает, что тип не является потокобезопасным, и вы не можете рассчитывать на согласованность, если вы считаете, что проблема с concurrency является проблемой.

Ответ 4

Определенно сомнительная практика.

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

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

Ответ 5

Отвращение к термину "запах кода" в стороне, вы можете быть правы - в зависимости от того, откуда он исходит, молча изменить значение, вероятно, не очень хорошо. Было бы лучше убедиться, что ваше значение действительно, а не только возврат к умолчанию.

Ответ 6

Я бы настоятельно рекомендовал реорганизовать его для проверки перед установкой свойства.

У вас всегда может быть метод, который больше похож:

T GetValidValueForProperty<T>(T suggestedValue, T currentValue);

или даже:

T GetValidValueForProperty<T>(string propertyName, T suggestedValue, T currentValue);

Если вы это сделаете, перед установкой свойства вы можете передать его в бизнес-логику для проверки, а бизнес-логика может вернуть значение свойства по умолчанию (ваше текущее поведение) ИЛИ (более разумное в большинстве случаев), вернуть currentValue, поэтому настройка не имела эффекта.

Это будет использоваться больше как:


T OurProperty
{
    get
    {
        return this.propertyBackingField;
    }
    set
    {
        this.propertyBackingField = this.GetValidValueForProperty(value, this.propertyBackingField);
    }
}

Неважно, что вы делаете, но важно проверить, прежде чем вы измените свое текущее значение. Если вы измените свое значение, прежде чем определить, хорошо ли новое значение, вы просите о проблемах в долгосрочной перспективе.

Ответ 7

Он может или не может "пахнуть", но я больше склоняюсь к "Да, он пахнет".

Устанавливает ли у параметра OurProperty значение по умолчанию логическую причину для этого, или это просто удобно сделать в коде? На практике, возможно, маловероятно, чтобы придумать сценарий, в котором это ожидалось бы, но я предполагаю, что в большинстве случаев вы должны бросать исключение и обрабатывать его где-то чисто.

Как установить значение по умолчанию, вы приближаетесь или отклоняете вас от описания функциональных спецификаций того, как приложение должно работать?

Ответ 8

Вы проверяете изменение после его завершения? Валидация должна быть выполнена до изменения свойства занятости.

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

Ответ 9

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

Ответ 10

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

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

Ответ 11

Кроме того, почему в мире это частичное? Использование частичных классов для чего-либо, кроме сгенерированной структуры кода, само по себе является кодовым кодом, поскольку вы, вероятно, используете их, чтобы скрыть сложность, которую нужно разделить в любом случае!

Ответ 12

Я согласен с Grzenio и добавлю, что лучший способ справиться с ошибкой проверки на уровне домена (например, бизнес-объекты) - это генерировать исключение. Это исключение может распространяться вплоть до уровня пользовательского интерфейса, где он может обрабатываться и интерактивно исправляться с пользователем. Однако, в зависимости от возможностей и технологий, это может оказаться не всегда возможным, и в этом случае вы, вероятно, должны проверять уровень UI (возможно, в дополнение к доменному слою). Он менее идеален, но может быть вашим единственным жизнеспособным вариантом. В любом случае установка его по умолчанию - это ужасная вещь, которая приведет к тонким ошибкам, которые невозможно диагностировать. Если это будет сделано в широком масштабе, у вас будет незаметная система в кратчайшие сроки (особенно если у вас нет модульных тестов, которые поддерживают вас).

Ответ 13

Аргумент, который я имею против этого, следующий. Предположим, что пользователь/производитель бизнес-объекта случайно ввел недопустимое значение. Затем этот шаблон замалчивает этот факт и по умолчанию очищает данные. Но правильный способ справиться с этим - это выбросить ошибку и заставить пользователя/производителя проверить/очистить свои входные данные.

Ответ 14

Я бы сказал, реализуем PropertyChanging и позволяю бизнес-логике утверждать/отклонять значение, а затем потом бросать исключение для недопустимых значений.

Таким образом, у вас никогда не было недопустимого значения. Это, и вы никогда не должны изменять информацию о пользователе. Что делать, если пользователь добавляет запись в базу данных и отслеживает ее для своих записей? Ваш код будет переназначать значение по умолчанию, и теперь он отслеживает неправильную информацию. Его лучше информировать пользователя как можно скорее.