Ложные реализации в C ++ - PullRequest
       7

Ложные реализации в C ++

6 голосов
/ 02 января 2011

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

  1. Создать интерфейс, который содержит все открытые функции класса как чисто виртуальные функции, а затем создать фиктивный класс, производный от него.
  2. Отметитьвсе функции (ну, по крайней мере, все, что нужно смоделировать) как virtual .

Я привык делать это первым способом в Java, и это тоже довольно часто(вероятно, так как они имеют выделенный тип интерфейса).Но я вряд ли когда-либо видел такие насыщенные интерфейсом конструкции в C ++, поэтому мне интересно.

Второй способ, вероятно, сработает, но я не могу не думать о нем как о некрасивом.Кто-нибудь делает это?

Если я пойду первым, мне понадобится помощь в присвоении имен.У меня есть аудиосистема, которая отвечает за загрузку звуковых файлов и воспроизведение загруженных треков.Для этого я использую OpenAL, поэтому я назвал интерфейс «Аудио» и реализацию «OpenALAudio».Однако это подразумевает, что весь специфичный для OpenAL код должен входить в этот класс, что является своего рода ограничением.Альтернативой было бы оставить имя класса «Audio» и найти другое для интерфейса, например «AudioInterface» или «IAudio».Что бы вы предложили и почему?

Ответы [ 4 ]

4 голосов
/ 02 января 2011

Точно так же, как я бы не создавал вручную фиктивные объекты в Java, я также не писал бы их вручную в C ++.Ложные объекты - это не просто заглушенные классы, а инструменты тестирования, которые выполняют автоматические проверки, например, проверяют, вызваны ли определенные методы, или что они вызываются по порядку и т. Д. Я бы взглянул на различные инфраструктуры ложных объектов для C ++., googlemock выглядит интересно, но есть и другие.

Что касается абстрагирования концепции управления аудио-ресурсами от реализации, я определенно предпочитаю использовать «интерфейс» C ++ (чистый виртуальный базовый класс).) с общим именем (например, Audio) и классом реализации, названным для того, что делает его особенным (например, OpenALAudio).Я предлагаю вам не встраивать слова «интерфейс» или «я» в имена ваших классов.Внедрение типов или программных концепций в имена уже много лет выходит из моды (и может привести к повсеместному переименованию, когда вы, например, повышаете «интерфейс» до полноценного «класса»).

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

3 голосов
/ 02 января 2011

«Но я вряд ли когда-либо видел такие насыщенные интерфейсом проекты в C ++», для вашей информации, я советую вам просто кратко взглянуть на способ работы Microsoft COM. Эта технология, основанная на C ++, полностью посвящена интерфейсу, насыщенному интерфейсом.

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

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

0 голосов
/ 02 января 2011

Рассматривали ли вы использование фиктивного фреймворка, например Бегемотики ?

Из вики :

class Foo {
private:
    IBar *bar;
public:
    Foo(IBar *bar);
    int a(); //calls IBar::c
};

class IBar {
public:
    virtual ~IBar() {}
    virtual void b() = 0;
    virtual int c(std::string) = 0;
};

void TestAFunctionInFoo() {
    MockRepository mocks;
    IBar *barMock = mocks.InterfaceMock<IBar>();
    Foo *newFoo = new Foo(barMock);
    mocks.ExpectCall(barMock, IBar::c).With("hello").Return(42);
    newFoo->a();
    delete newFoo;
}
0 голосов
/ 02 января 2011

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

Должен признать, что у меня нет практического опыта в этом, но мне кажется, что чем меньше вы навязчивы в своем исходном коде, тем лучше.

...