Frage

Hier ist die Situation: Ich habe eine Klasse bekam, die zu viel tut. Es ist in erster Linie für die Konfiguration des Zugriff auf Informationen, aber es hat auch die Datenbankverbindung. Es ist als Singleton implementiert, so dass dies macht auch Unit-Tests ist es schwierig, da die meisten Code ist ziemlich eng gekoppelt zu. Dies ist umso problematischer, da es eine Import-Zeitabhängigkeit schafft (wir tun dies in Python), was bedeutet, dass bestimmte Module in einer bestimmten Reihenfolge importiert werden muß. Im Idealfall würde Ich mag beide diese in zwei Klassen spalten und es sich um eine nicht-Singleton machen.

Zum Glück hat mein Arbeitgeber auf die Tatsache aufgewärmt, dass diese Art der Prüfung gut ist, und ist bereit, mich zu erlauben, Änderungen so zu machen, wenn es Code mehr überprüfbar macht. Ich bezweifle jedoch, dass sie bereit sind, mir zu erlauben, verbringen zu viel Zeit darauf. Und ich würde lieber dieses Problem behebt inkrementell anstatt zu versuchen, zu radikal zu sein.

Also, ich sehe drei Möglichkeiten hier:

  1. Brechen Sie das Konfigurationsobjekt in ein (Singleton) Konfigurationsobjekt und ein (nicht-Singleton) Datenbankobjekt. Dies würde zumindest mir erlauben, die Datenbank als Import-Zeitabhängigkeit zu entfernen.
  2. Stellen Sie die Konfiguration einer nicht-Singleton-Objekt und es auf Objekte übergeben, die es brauchen. Ich glaube, dass dies eine besseren Adressen unsere kurzfristigen Bedürfnisse, aber ich denke, es wäre deutlich mehr Zeit in Anspruch nehmen.
  3. Sie etwas, das ich hatte nicht gedacht, dass Sie in Ihrer Antwort vorschlagen. : -)

Also, was soll ich tun?

War es hilfreich?

Lösung

Ich glaube, Sie auf dem richtigen Weg sind in zwei Klassen zu trennen. Sie könnten mit einem Werk betrachten möchten, dass Ihre Datenbankkontext / Verbindung zu erstellen, wie gebraucht. Auf diese Weise können Sie die Verbindung als eine Einheit der Arbeit Einheit behandeln, die nicht benötigten erstellt / entsorgt werden als als eine einzige Verbindung um für das Leben des Objekts zu halten. YMMV, though.

Wie für die Konfiguration, dann ist dies ein Fall, wo finde ich, dass ein Singleton die richtige Wahl sein. Ich würde es nicht unbedingt Dump, nur weil es schwer zu Unit-Test ist. Vielleicht möchten Sie es prüfen, bauen jedoch auf eine Schnittstelle zu implementieren. Anschließend können Sie Dependency Injection verwenden, um eine Pseudo-Instanz der Schnittstelle während des Tests zur Verfügung zu stellen. Ihre Produktion Code würde entweder gebaut, um die Singleton-Instanz zu verwenden, wenn der injizierte Wert null ist oder die einzelne Instanz zu injizieren. Alternativ können Sie die Klasse konstruieren Neuinitialisierung über eine private Methode, und rufen Sie diese in Ihrem Setup / Teardown Prüfverfahren zu ermöglichen, um sicherzustellen, dass es die richtige Konfiguration für Ihre Tests hat. Ich ziehe die ersteren zur letzteren Implementierung, obwohl ich es auch benutzt habe, wenn ich keine direkte Kontrolle über die Schnittstelle.

die Änderungen schrittweise zu machen ist definitiv der Weg zu gehen. Einwickeln die aktuelle Funktionalität mit Tests, wenn möglich, und dafür zu sorgen, dass diese Tests noch nach Ihren Änderungen passieren (aber nicht die, die direkt mit Ihren Änderungen, natürlich tun) ist ein guter Weg, sicherzustellen, dass Sie sind nicht brechen anderen Code .

Andere Tipps

Es ist schwer, ohne zu sehen, den Code zu kennen, aber warum nicht tun, was Sie sagen - tut es inkrementell? Zuerst haben Schritt 1, teilen Sie die Datenbank aus.

Wenn das schnell dann zurückgehen, und Sie haben jetzt nur 1 kleinere Objekt ein Singleton zu stoppen und nicht zu sein als 2. 2 So soll schneller seinen Schritt. Oder in diesem Stadium könnten Sie einen anderen Code sehen, die aus dem Singleton Refactoring werden können.

Hoffentlich können Sie Schritt-für-Schritt reduzieren, was in der Singleton ist, bis es verschwindet, ohne jemals eine große Zeitsteuer einem Schritt zu zahlen.

Zum Beispiel könnte vielleicht ein Teil der Konfiguration Singleton zu einem Zeitpunkt vorgenommen werden, wenn die Teile der Konfiguration unabhängig sind. Vielleicht GUI-Konfiguration links Singleton während fileconfiguration Refactoring oder etwas ähnliches?

Option 1 ist, was ich tue in allen meinen apps: Konfigurationsobjekt Singleton und Datenbankobjekte auf Verlangen oder injiziert.

Mit dem cofiguration Objekt als ein Singleton immer eine perfekte Passform für mich gewesen ist. Es gibt nur eine Konfigurationsdatei, und ich will es immer lesen, wenn die Anwendung gestartet wird.

Entschuldigen Sie die Tatsache, dass ich kenne keinen Python, so dass ich hoffe, dass jeder Pseudo-Code Sinn macht ...

würde ich das Objekt in zwei Teile zunächst geteilt, so dass die Zuständigkeiten Ihrer Singleton kleiner sind, dann würde ich die restliche Konfiguration Singleton nehmen und es in eine normale Klasse ändern (als ob Sie Ihren zweiten Vorschlag werden auszuführen ).

Sobald ich bekam würde so weit würde ich eine neue, Wrapper Singletons erstellen, die die Methoden der Konfigurationsklasse macht:

class ConfigurationWrapper : IConfigurationClass 
{
    public static property ConfigurationWrapper Instance;

    public property IConfigurationClass InnerClass;

    public method GetDefaultWindowWidth()
    {
        return InnerClass.GetDefaultWindowWidth();
    }

    etc...
}

Nun das erste, was die Anwendung tut, ist eine Instanz der ConfigurationClass in die Umhüllung injizieren.

ConfigurationClass config = new ConfigurationClass()
ConfigurationWrapper.Instance.InnerClass = config;

Schließlich können Sie Klassen bewegen, die derzeit auf dem Singleton verlassen über Wrapper Singleton (die eine schnelle Entdeckung sein sollte und ersetzen). Jetzt können Sie die Klassen einer nach dem anderen konvertieren die Config-Objekt in durch ihre Erbauer zu nehmen Phase abzuschließen 2. Gibt es, dass Sie nicht Zeit, um die Wrapper Singleton zu tun haben, können verwendet werden. Sobald Sie sie alle über euch bewegt haben, können von der Hülle loswerden.

Auf der anderen Seite können Sie das Refactoring der Verbräuche ignorieren und einfach eine verspottete Konfigurationsklasse in den Singleton-Wrapper zum Testen injizieren - im Wesentlichen eines schlechter Dependency Injection des Mannes.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top