2009-08-27 5 views
1

Ich verwende ein einfaches 3-Tier-Design. Aus Gründen der Flexibilität (und des Testens) wollte ich, dass die Datenschicht abstrakt ist und die konkrete Klasse in meinem Code angibt. Aber wie soll ich das an meine Geschäftsobjekte weitergeben? Hier ist ein Beispiel (Pseudocode):n-Tier-Design - beste Möglichkeit, Daten zu übergeben Objekt abrufen

abstract class IDataLayer 
{ 
    PersonData GetPerson(int); //PersonData would be a row of data from a table for example 
    JobData[] GetJobs(int); 
    void UpdatePerson(PersonData); 
} 

class ConcreteDataLayerSQL : IDataLayer 
{ 
... 
} 
class ConcreteDataLayerXML : IDataLayer 
{ 
... 
} 

class PersonBAL 
{ 
    void PersonBAL(personId) 
    { 
     //What goes here? 
    } 

    JobBAL[] GetJobs() 
    { 
     //What goes here? 
    } 
} 
class Program 
{ 
    static void Main() 
    { 
     person = new PersonBAL(1); 
    } 
} 

Das Problem ist also, wie funktioniert PersonBAL wissen, welche ConcreteDataLayer zu benutzen? Ich denke zwischen ein paar Optionen:

1: übergeben Sie die konkrete Datenschicht an die Person. Dies wird ein Schmerz, wenn Sie neue Klassen hinzufügen, die mit der Datenschicht interagieren müssen (etwas wie neue PersonBAL (IDataLayer, int), dann neue JobBAL (IDataLayer, int) usw.)

2: Erstellen Sie eine statische Objekt, das die zu verwendende Datenschicht enthält (Lesen: globale Variable)

Irgendwelche anderen Ideen?

Antwort

1

Das Problem, das Sie lösen möchten, ist "Abhängigkeitsinjektion".

Angenommen, dies ist .NET-Code (Ihre Pseudo-Code-Sprache sieht sehr ähnlich wie C# aus), möchten Sie vielleicht in ein Framework wie Spring.NET schauen, das für diese Art von Dingen gedacht ist.

+0

Während ich die Klarstellung zu dem Begriff schätze, hätte ich gerne eine bessere Lösung, als einen Rahmen zu bekommen, um das Problem zu lösen. Wie geht das Framework mit dem Problem um? –

0

Ich denke, das Übergeben der Klasse in jedem Konstruktor wäre eine Herausforderung für den Grund, den Sie aufgelistet haben, und weil das Ändern des Codes, um eine andere Klasse zu verwenden, eine fehleranfällige Aufgabe wäre.

Dependency Injection ist der Kern des Spring-Frameworks. Spring verwendet XML-Konfigurationsdateien, um die Beziehungen zwischen Klassen zu beschreiben. Für Ihren Anwendungsfall können Sie den spezifischen Typ angeben, der in der Konfiguration instanziiert werden soll. Sie müssen also nur eine Änderung vornehmen, um die Implementierungen zu wechseln.

Spring ist ein bekanntes und getestetes Framework, aber Sie brauchen es natürlich nicht, um das Problem zu lösen. Sie könnten sehr gut Ihren eigenen Code für Konfigurationsdateien schreiben. Wie auch immer, dies ist im Wesentlichen eine Variation der zweiten Option, die Sie erwähnt haben.

0

Sie könnten eine Schicht von Indirection in Ihrem Code, so dass Sie nie direkt eine PersonBAL konstruiert haben, stattdessen haben Sie eine PersonBALFactory, die Sie verwenden, um Ihre PersonBAL Instanzen zu konstruieren. Die Factory hat die Abhängigkeit von dem IDataLayer, der über den Konstruktor übergeben wird (und der zum Zeitpunkt des Starts der Anwendung verdrahtet ist). Sie sagen der Factory, dass sie eine Person mit einer PersonId erstellt und eine neue PersonBAL erstellt, die die ID und der IDataLayer. Auf diese Weise muss sich der Benutzer nicht darum kümmern, welcher IDataLayer Sie verwenden, er wird beim Start in der Anwendungskonfiguration eingerichtet, der Benutzer fordert nur neue PersonBAL mit den ihm bekannten Informationen an.

DI-Frameworks helfen Ihnen bei der Konfiguration der Abhängigkeitsinjektion, damit die richtigen Typen an die Konstruktoren übergeben werden und die Konfiguration der Fabriken (und der Abhängigkeiten von den Fabriken) automatisch und einfacher wird viele Fabriken oder komplexe Abhängigkeitsgraphen.

Verwandte Themen