Ответ 1
Должен ли я реализовывать классы с использованием чистого класса интерфейса в качестве базы, чтобы упростить создание поддельных тестовых объектов?
- Это заставило бы меня создавать множество виртуальных методов. Это повлияет на производительность?
Обходной путь, который я часто использую, - это templatize класс вместо того, чтобы скрывать его за интерфейсом. Затем я могу передавать объекты тестирования/макета в качестве параметров шаблона при тестировании, а реальные объекты - в противном случае. Таким образом избегается поражение виртуальных функций.
Edit
Хорошо, простой пример:
С ООП и интерфейсами вы можете написать такую функцию, как:
void Foo(IBar& someBar) { ... }
Эта функция принимает параметр, реализующий интерфейс IBar
, и делает что-то с ним. Если вы хотите перейти в фиктивную реализацию mock, вы просто напишите mock-объект, который наследует от IBar
, и передайте его на Foo
. Простой и понятный.
Но вы можете добиться того же, что и с шаблонами:
template <typename BarType>
void Foo(BarType& someBar) { ... }
... и что это. Тело Foo
может быть практически без изменений. До тех пор, пока тип, переданный функции, предоставляет все необходимые нам члены, он будет работать без формального наследования класса интерфейса и без накладных расходов на виртуальные функции и полиморфизм во время выполнения.