Реализация Singleton и интерфейса

У меня есть класс интерфейса Interface с чистыми виртуальными методами.

class Interface
{
public:
    virtual void DoSomething() = 0;
}

Кроме того, существует класс Implementation, который реализует интерфейс.

class Implementation : public Interface
{
    void DoSomething();
}

В моей программе мне нужно иметь Singleton (единственный экземпляр) пары Implementation/Interface. В программе много пар Implementation/Interface, но очень мало классов Implementation для одного класса Interface.

ВОПРОСЫ:

  • Должен ли я вызывать класс Interface или Implementation из остальной части моей программы всякий раз, когда мне нужно использовать класс? Как именно я должен это делать?

     //Interface needs to know about Implementation
     Interface * module = Interface::Instance();
    
     //No enforcement of Interface
     Implementation * module = Implementation::Instance();
    
     //A programmer needs to remember Implementation and Interface names
     Interface * module = Implementation::Instance();
    
     //May be there is some better way
    
  • Как выглядит метод Instance()?

Ответы

Ответ 1

"1) Должен ли я запускать класс интерфейса или реализации из остальной части моей программы всякий раз, когда мне нужно использовать класс? Как именно это сделать?"

Используйте интерфейс, который будет меньше загромождать ваш код вызовами Implementation::Instance():

 Interface& module = Implementation::Instance();
       // ^ 

Обратите внимание, что ссылка, назначение и копия не будут работать.

"2) Как должен выглядеть метод Instance()?

Общий консенсус заключается в использовании подхода Скотта Мейера:

 Implementation& Instance() {
     static Implementation theInstance;
     return theInstance;
 }

Лучшей альтернативой является не использовать синглтон вообще, а сделать код готовым к работе только с Interface:

 class Interface {
      // ...
 };

 class Impl : public Interface {
      // ...
 };

 class Client {
     Interface& if_;
 public:
     Client(Interface& if__) : if_(if__) {}
      // ...
 }

 int main() {
     Impl impl;
     Client client(impl);
 };