Fabrik-Methode extrahieren und überschreiben

Hier geht es um die Erzeugung von Objekten in Konstruktoren. Klasse WantToTest erzeugt im Konstruktor ein Wrapperobjekt der Klassen A und B. Klasse A wird mit 20 initialisiert, was 20 Datenbank-Verbindungen bedeutet.

Hier das Szenario in C++

#include <iostream>
#include <tr1/memory>

class A
{
  public:
    A(int n)
    : m_NumberOfDBConnections(n)
    {}

    A()
    : m_NumberOfDBConnections(0)
    {}

    int m_NumberOfDBConnections;
};

class B
{
  public:
    B(int i)
    : i(i)
    {}

    int i;
};
typedef std::tr1::shared_ptr<A> PtrA;
typedef std::tr1::shared_ptr<B> PtrB;

class AB
{
  private:
     PtrA m_A;
     PtrB m_B;

  public:
  AB(PtrA a, PtrB b)
  : m_A(a), m_B(b)
  {
  }

  AB ()
  {}

  A* GetA()
  {
    return m_A.get();
  }
};

typedef std::tr1::shared_ptr<AB> PtrAB;

class WantToTest
{
  public:

  WantToTest()
  {
    PtrA a (new A(10));
    PtrB b (new B(20));

    PtrAB ab ( new AB(a,b));

    m_AB = ab;

  }

  private:
    PtrAB m_AB;
};

Da in Tests keine Datenbank-Kommunikation vorkommen soll, wollen wir dies gerne verhindern. Wir wollen wie bei Extract Method and Overwrite Call, den Kontruktoraufruf extrahieren und überschreiben:

class WantToTestCreationExtracted
{
  public:

  WantToTestCreationExtracted()
  {
    m_AB = CreateAB();
  }

  PtrAB CreateAB()
  {
    PtrA a (new A(10));
    PtrB b (new B(20));

    PtrAB ab ( new AB(a,b));

    return ab;

  }

  AB* GetAB()
  {
    return m_AB.get();
  }

  private:
    PtrAB m_AB;
};

class CanTest: public WantToTestCreationExtracted
{
  PtrAB CreateAB()
  {
    PtrA a (new A(0));
    PtrB b (new B(0));

    PtrAB ab ( new AB(a,b));

    return ab;
  }
};

Folgender Test spuckt aber 10 aus:

int main()
{
  CanTest t;
  A* a = t.GetAB()->GetA();
  std::cout << (a->m_NumberOfDBConnections);
  return 0;
}

Das lässt sich damit erklären, dass C++ zum Zeitpunkt des Konstruktoraufrufs der Basisklasse keine abgeleitete Klasse kennt. So lautet denn Scott Meyers Tip 9 in Effektiv C++ programmieren auch, niemals während der Konstruktion oder der Zerstörung virtuelle Funktionen aufzurufen, da diese Funktionen nicht über die Basisklasse hinauskommen.

0 Responses to “Fabrik-Methode extrahieren und überschreiben”


  • No Comments

Leave a Reply