Должен ли я использовать макеты в производственном коде? - PullRequest
10 голосов
/ 31 июля 2009

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

Мне нужно написать пустые классы (для реализации интерфейса) или использовать систему макетов, такую ​​как moq.

Таким образом, вопрос заключается в том, не нарушают ли системы производительности или некоторую читаемость рабочего кода?

обновление
Пример:

interface IRocketSystem
{
   void LaunchTheRocket();
}

class SimulationRocketSystem:IRocketSystem
{
...
}

class RocketSystem:IRocketSystem
{
...
}

Я обнаружил, что у меня есть классы SimulationRocketSystem в производстве, они маленькие и не имеют много в теле. система mock имеет одну строку кода ( new Mock (). Object ) для замены классов следующим образом.

плюсы за издевки:
меньше пустых классов в проекте.

Ответы [ 8 ]

10 голосов
/ 02 августа 2009

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

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

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

9 голосов
/ 31 июля 2009

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

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

6 голосов
/ 31 июля 2009

Что не так с пустым классом?

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

Я думаю, что помещать фиктивный код любого вида вне тестов - плохая политика.

2 голосов
/ 02 августа 2009

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

Хорошо бы использовать полиморфизм над операторами if для контроля того, что должно произойти.

Пример, скажем, если вы хотите, чтобы регистрация была необязательной. Императивный подход заключается в предоставлении boolean isLogging. Затем каждый раз проверяйте логическое значение как if (isLogging) { ...logging code... }.

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

Это просто хорошее объектно-ориентированное программирование.

2 голосов
/ 31 июля 2009

Возможно, это немного необычно, поэтому в моих комментариях и т. Д. Мне будет ясно, что это необходимая функциональность. Иначе кто-то будет очень смущен тем, как тестовый код попал в производство!

Что касается производительности, как всегда, вам нужно измерить ее, поскольку она настолько специфична. Тем не менее, я бы рискнул предположить, что, поскольку вы издеваетесь над функциональностью, которую вы не написали, она вполне может быть намного быстрее , чем ваша макетированная реализация. Это то, что вам может понадобиться, чтобы рассказать своим пользователям, поскольку, когда вы предоставляете окончательную работающую реализацию, они вполне могут увидеть снижение производительности: -)

Решение real состоит в том, чтобы предоставить фиктивную реализацию существующему интерфейсу и предоставить реальную реализацию позже.

1 голос
/ 31 июля 2009

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

1 голос
/ 31 июля 2009

Я действительно не знаю о проблемах производительности. Но ИМХО, вы должны быть очень осторожны с удобочитаемостью. Не лучше ли объявить один или несколько интерфейсов и реализовать их двумя различными способами?

- EDIT

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

Ну, это личное мнение. Ваш код будет использовать шаблон, отличный от ожидаемого. Это похоже на «соглашение о конфигурации». Если вы не используете соглашение, вам будет труднее его настроить (в вашем случае, документирование и разъяснение того, что вы делаете).

0 голосов
/ 31 июля 2009

Мне нужно написать пустые классы или использовать систему издевательств, такую ​​как moq.

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

...