Я работал в месте под названием Newfire в конце 90-х. Прежде чем финансирование высохло, у нас был механизм, который мог представить иммерсивный мир, который составлял 10 000 квадратных километров с разрешением 10 см. Вы могли вложить огромное число игроков сразу и постоянно деформировать среду. Этот механизм работал в частоте кадров на P200 с картой Voodoo 2.
большая часть механизма была записана в тщательно настроенном C++. Весь игровой код был записан в C или C++ или Java. У меня также был код прототипа, который мог определить поведение объекта с помощью нажатия вниз автоматы, которые могли сделать очень достойный AI. Не потребовалось почти процессорного времени. Выполнение игровой логики затмилось путем рендеринга.
Однажды, у меня была демонстрация Игры Conway Жизни, работающей в Java с помощью нашего рендерера программного обеспечения. Ячейки были кубами, положенными в плоскости, которая появилась или исчезла и изменила цвет как их в возрасте большего количества поколений. В то время как игра работала с фиксированной скоростью генерации 4 поколений в секунду, 3D дисплей достигал 20 + кадр/с, снова на P200 с программное обеспечение рендерер.
, Таким образом, ответ не является определенно C++. Ответ, как любая проблемная область, является языком, который работает лучшее в том домене. C++ работает хорошо в том домене для механизма визуализации, но для фактической игровой логики и правил, много языков работает хорошо. Python является большим. C# является большим. Java является большим.
Похоже на Нулевой объект . Я не верю в использование фреймворков для этого по двум причинам.
Во-первых, это вредит читабельности. Вы реализуете интерфейс с помощью пустого класса с соответствующим именем, а затем документируете намерение внутри этого класса. С другой стороны, если вы используете фиктивный фреймворк, вашу документацию нужно где-то встроить в код. Более того, это будет сбивать с толку, так как люди обычно ожидают фиксации в тестовом коде и не понимают вашего намерения использовать макеты.
Во-вторых, вы должны подумать о том, что произойдет, если кто-то изменит интерфейс. Что делать, если метод добавлен? Должен ли он по умолчанию возвращать null - как это делают некоторые фреймворки? Что, если метод должен вернуть какое-то конкретное возвращаемое значение в соответствии с контрактом интерфейса. Если у вас есть конкретная реализация, то компилятор хотя бы в некоторой степени вас защитит. Если вы используете фиктивный фреймворк, вам может не повезти.
Вы называете это имитацией, но похоже, что то, что вы делаете, - это просто правильное разделение проблем.
Хорошо использовать полиморфизм по сравнению с операторами if, чтобы контролировать, что должно произойти. .
Например, если вы хотите, чтобы ведение журнала было необязательным. Обязательный подход - предоставить логическое значение isLogging
. Затем каждый раз проверяйте логическое значение, например if (isLogging) {... код регистрации ...}
.
Но если вместо этого вы отделяете фактический код журнала как проблему для другого объекта, тогда вы можете установите этот объект на тот, который делает то, что вы хотите. Помимо наличия логгера с нулевой маршрутизацией, который представляет отключенное ведение журнала и тот, который фактически записывает в файл, он также позволяет вам предоставить объект журнала, который записывает в базу данных вместо файла, он позволяет вам добавлять функции в регистратор, такие как как ротация лог-файла.
Я действительно не знаю о проблемах с производительностью. Но IMHO, вы должны быть очень осторожны с читабельностью. Разве не лучше объявить один или несколько интерфейсов и реализовать их двумя разными способами?
- РЕДАКТИРОВАТЬ
Мокинг может быть проще и требует меньше строк кода, но увеличивает время обучения вашему коду. Если новый парень придет и увидит ваш код, ему потребуется больше времени, чтобы понять. Лично я считаю, что это еще не реализованная функция кода. Но если бы существовала другая реализация интерфейса или какое-то другое хорошее дизайнерское решение, я бы «понял» гораздо быстрее и чувствовал бы себя более защищенным при изменении кода.
Что ж, это личное мнение. В вашем коде будет использоваться иной шаблон, чем ожидалось. Это похоже на «соглашение по конфигурации». Если ты'
Что не так с пустым классом?
В самом деле, он будет заменен реальным классом, так что вы можете начать с настоящего класса.
Я думаю, добавление фиктивного кода любого рода вне тестов - плохая политика.
Мок-объект - это то, что вы используете для тестирования, так как он позволяет вам утверждать, что он был вызван правильно. Мне кажется, то, что вы ищете, больше похоже на заглушку или прокси-объект.
Поскольку вы в конечном итоге реализуете рассматриваемый класс, было бы бессмысленно иметь фиктивный фреймворк, делающий это за вас, ИМО. Почему бы просто не создать класс и не реализовать его по мере необходимости.
Возможно, это немного необычно, поэтому в своих комментариях и т. Д. Я бы пояснил, что это обязательная функциональность. В противном случае кто-то будет очень сбит с толку относительно того, как тестовый код попал в рабочую среду!
Что касается производительности, как всегда, вам необходимо измерить ее, поскольку она настолько специфична. Однако я рискну предположить, что, поскольку вы имитируете функциональность, которую не написали, она вполне может быть намного быстрее , чем ваша смоделированная реализация. Возможно, вам потребуется проинформировать своих пользователей, поскольку, когда вы предоставляете окончательную функциональную реализацию, они вполне могут увидеть снижение производительности: -)
Реальное реальное решение - предоставить фиктивную реализацию для существующий интерфейс, а затем предоставить реальную реализацию.
Мой совет - не запускайте его в производство. Никогда не вводите в производство ничего, что может замедлить, сломать или иным образом привести к потере работы :)
Но более важным, чем то, что я думаю, является политика вашей компании и что думает ваш менеджер? Вы никогда не должны думать о принятии такого решения самостоятельно - это называется CYA.
. Мне нужно выбрать написание пустых классов или использование имитирующей системы, такой как moq.
Обернуть его в отдельный компонент фасада / адаптера и использовать внутренние классы должно быть достаточно. Если ваши пустые классы нужно передавать по системе, у вас проблема.