2008-10-01 10 views

Antwort

10

Es gibt mehrere Gründe nicht allgemein als gutes Design angesehen, von denen einige Probleme beim Testen der Einheit und Schwierigkeiten bei der Handhabung von Fehlern verursachen.

Der Hauptgrund, warum ich dies nicht tun würde, ist, dass Ihr Objekt und die Datenzugriffsebene jetzt sehr eng miteinander verbunden sind. Dies bedeutet, dass jede Verwendung dieses Objekts außerhalb des ursprünglichen Entwurfs erhebliche Nacharbeiten erfordert. Was wäre zum Beispiel, wenn Sie auf eine Instanz stießen, in der Sie dieses Objekt verwenden mussten, ohne dass Werte zugewiesen wurden, um beispielsweise eine neue Instanz dieser Klasse beizubehalten? Sie müssen jetzt entweder den Konstruktor überladen und dann sicherstellen, dass Ihre gesamte andere Logik diesen neuen Fall behandelt oder erben und überschreiben.

Wenn das Objekt und der Datenzugriff entkoppelt sind, können Sie eine Instanz erstellen und dann nicht hydratisieren. Wenn Sie ein anderes Projekt verwenden, das dieselben Entitäten verwendet, aber eine andere Persistenzebene verwendet, sind die Objekte wiederverwendbar.

auch sagen, dass ich den einfacheren Weg der Kopplung in Projekten in der Vergangenheit stattgefunden habe :)

+0

"Nachdem ich gesagt habe, dass ich den leichteren Weg der Kopplung in Projekten in der Vergangenheit genommen habe :)" Ich mag das, schlägt vor, dass der Kontext sehr wichtig ist. – Sully

1

Das einzige Problem, das ich mich vorstellen kann mit diesem Ansatz ist, dass Fehler aus der DB-Initialisierung als Ausnahmen von dem Konstruktor propagiert werden.

11

Nun .. ich würde nicht. Aber meine Vorgehensweise beinhaltet normalerweise, dass die Klasse NICHT dafür verantwortlich ist, ihre eigenen Daten zu erhalten.

4

Ja, Sie können es tun, aber es ist nicht das beste Design, und Fehlerbehandlung in Konstruktoren ist nicht so sauber wie anderswo.

7

Sie die Einweg Muster verwenden können, wenn Sie auf eine DB-Verbindung verweisen:

public class MyClass : IDisposable 
{ 
    private Database db; 
    private int? _id; 

    public MyClass() 
    { 
     db = new Database(); 
    } 

    public int Id 
    { 
     get 
     { 
      if (_id == null) _id = db.GetIdFor(typeof(MyClass)); 
      return _id.Value; 
     } 
    } 

    public void Dispose() 
    { 
     db.Close(); 
    } 
} 

Verbrauch:

using (var x = new MyClass()) 
{ 
    /* ... */ 

} //closes DB by calling IDisposable.Dispose() when going out of "using" scope 
-3

Warum sollte jemand einen Mock-Objekt/Stub anstelle der realen Sache verwenden? Würden Sie zustimmen, dass Autohersteller Pappmodelle für Crashtests verwenden sollten?

+2

Für einen Integrationstest verwenden Sie unbedingt die gesamte Ebene. Für einen Komponententest möchten Sie nur überprüfen, ob Ihr Objekt das aufruft, was es sagt. Sie können einen anderen Einheits- oder Integrationstest verwenden, um zu überprüfen, ob seine Ressourcen das ausführen, was sie auch sagen. –