Laden...

Verbesserungsvorschläge für Architektur (Data Access Layer, Repository)

Erstellt von Doltsche vor 12 Jahren Letzter Beitrag vor 12 Jahren 1.911 Views
D
Doltsche Themenstarter:in
249 Beiträge seit 2009
vor 12 Jahren
Verbesserungsvorschläge für Architektur (Data Access Layer, Repository)

Hallo Community

Im Rahmen meiner Ausbildung muss ich mit jemandem eine kleine Anwendung zum Erfassen von Zeiten Schreiben. Als Datenbank müssen wir Microsoft Access 2010 verwenden. Es ist daher nicht wirklich eine Client-Server Applikation.

Wie dem auch sei versuche ich ein vernünftiges Design zu erstellen und ersuche nun um eure Vorschläge. Mein bisheriges Desgin ist im Anhang als PNG zu finden.

Ich hoffe ihr koennt mir einige Verbesserungsvorschlaege machen =)

Beste Gruesse

Samuel

Edit:

Projektziel: Anwendung zum Verbuchen von Zeiten im Bezug auf bestimmte Aufgaben, die wiederum in Relation zu einem Projekt stehen. Insgesamt gibt es vier Entitaeten: Project, Customer, Employee, Task
Fuer dieses Projekt duerfen wir leider kein LINQ oder sowas verwenden. Die Abfragen muessen direkt mit SQL-Statements erfolgen. Das macht es natuerlich schwieriger einen DataAccessLayer zu verwenden bzw. wirft die Frage auf, ob ein solcher in diesem Falle ueberhaupt Sinn macht?

DAL: Zweck dieses Layers ist es, den technischen Zugriff auf die Datenbank abzukapseln. Der Benutzer braucht somit lediglich entsprechende SQL-Statements der Command-Klasse zu uebergeben und erhaelt .NET spezifische Datentypen wie DataTable als Rueckgabewert.

Wax machte mich darauf aufmerksam, dass das nur mit absolutem basic-SQL geht. Sobald spezielle DB-Funktionen hinzukommen, ist dieser Layer anzureichend.

DAL.Base: Beinhaltet zurzeit lediglich ein ConnectionString-Objekt, welches ueber die erbende Klasse initialisiert wird. Der ConnectionString wird ueber das ConfigurationUtil aus einer Settingsdatei gelesen.

DAL.Command: Kapselt im Grunde lediglich den Aufruf verschiedener Methoden (Wie das erstellen eines DatenbankAdapters oder das Oeffnen einer Verbindung zu der Datenbank).

Model.Repository.IRepository: Das IRepsitory legt nochmals einen Layer auf den Data Access Layer. Ein wesentliches Feature ist hier das Casting der einzelnen Objekte (Datensatz zu Objekt). Ueber die OnSubmit-Methoden wird im Hintergrund ein SQL-Query generiert und beim Aufruf von SubmitChanges() ausgefuehrt.
Die Execute...Sql Methoden muessten noch geaendert werden, dass sie eine Liste vom Typ des entsprechenden Objekts zurueckgeben anstelle von z.B: DataTable (fiel mir erst jetzt auf. IList<BaseObject>).

Model.BaseObject: Beinhaltet zurzeit lediglich die Datenbankspezifische ID eines Objekts. Diese Id kann nur einmal gesetzt werden. Wurde die ID bereits gesetzt wird eine Exception geworfen.

**Weshalb suche ich ueberhaupt nach Verbesserungsvorschlagen: **Erfahrungsgemaess suche ich oftmals nach zu komplexen Loesungen bzw. versuche Konzepte wie Repository oder Data Access Layer umzusetzen obwohl das vieleicht unnoetig ist.

731 Beiträge seit 2006
vor 12 Jahren

Moin,

das erste was mir auffällt hat mit folgendem Satz zu tun:

"...the user doesn´t need to worry about the specific database..."

Das funktioniert nur solange, wie der Entwickler absolute "Basic-SQL-Statements" schreibt. Sobald irgendeine spezifische DB-Funktion im SQL-String vorkommt, klappt es nicht mehr.

MfG
wax

49.485 Beiträge seit 2005
vor 12 Jahren

Hallo Doltsche,

also einfach zu schreiben: "Hier ist meine Architektur, was kann ich besser machen?", geht schon sehr in Richtung [Hinweis] Wie poste ich richtig? Punkt 4a (analog zu den Code-Reviews).

Was stört dich an der Architektur? Warum glaubst du überhaupt, dass man was besser machen kann? Gibt es konkrete Anhaltspunkt? Wenn ja, welche sind das? Wenn nein, warum stellst du die Frage überhaupt?

An welchen Stellen vermutetest du den größten Verbesserungsbedarf? Welche Alternativen hattest du selbst erwogen? Warum hast du sie als schlechter als deine jetzige Architektur eingeschätzt?

Davon abgesehen müsstest du deutlich mehr dazu schreiben, wie deine Anwendung funktionieren soll, damit man beurteilen kann, ob die Architektur dazu passt.

herbivore

D
Doltsche Themenstarter:in
249 Beiträge seit 2009
vor 12 Jahren

Hallo Community

@Herbivor: Du hast recht 😉. Ich habe den Beitrag nun entsprechend ergaenzt. Zuerst dachte ich, dass sei sofort auf dem UML ersichtlich. Aber das stimmt in diesem Falle nicht ganz.

Das funktioniert nur solange, wie der Entwickler absolute "Basic-SQL-Statements" schreibt. Sobald irgendeine spezifische DB-Funktion im SQL-String vorkommt, klappt es nicht mehr.

Ja, das ist jezt in der Tat etwas verzwickt. Wie wird sowas von Persistenz-Frameworks gehandelt? Oder macht es gar keinen Sinn einen Data Access Layer zu schreiben ohne ein Persistenz-Framework? Leider ist es Projektvorgabe die Querys direkt mit SQL auszufuehren. Was gaebe es sonst noch fuer Loesungen?

Ist es Sinnvoll das Repository-Package innerhalb des Package Model einzugliedern?

Macht die Klasse DAL-Base ueberhaupt Sinn, da diese ja nur das ConnectionString-Objekt enthaelt?

Beste Gruesse

Samuel

S
443 Beiträge seit 2008
vor 12 Jahren

Hi,

Das funktioniert nur solange, wie der Entwickler absolute "Basic-SQL-Statements" schreibt. Sobald irgendeine spezifische DB-Funktion im SQL-String vorkommt, klappt es nicht mehr.

Ich habe beim entwickeln meines ORMappers die Frage von mir geschoben.
Mein Ziel war einen ORMapper zu bieten der zu jeder datenbank passt und die möglichkeiten jeder Datenbank ausnützt. (geht ja nicht)

also habe ich mir einen "Dummen" ORMapper geschrieben, der Intern für jeden Datenbank einen "Connector" hat.
dieser connector liefert eigentlich nur SQLStrings die gegen die Datenbank gefahren werden können.
Die SQLStrings werden aus meinen "Dto" Dateien ausgelesen. Diese Datei ist mit Attributen vollgestopft. (TableMappingAttribute, FieldMappingAttribute, PrimaryKeyattribute, ForeinKeyAttribute, etc)
Mit dieser Vorgehensweise kann ich bei einem einzelnen Select auch JOIN befehlen zusammen bauen. Wie ein JOIN aussehen muss weis der connector, was er joinen muss kann er aus bekommt er vom ORMapper ausgelesen.

Damit bin ich Datenbank unabhängig solange ich nur SELECT UPDATE und DELETE verwende. Genügt für den grösseren Teil den die Anwendung braucht.

Es genügt aber nicht für alle Programme und dafür habe ich ein neues Attribut erfunden, das CommandAttribute
dieses CommandAttibute kann clientseitig verwendet werden um einen SQL-Procedure aufzurufen.
Damit ist der Verwender des ORMappers in der Verantwortung sich einen umstieg auf eine andere Datenbank zu erschweren. Nicht mehr Deine.

Durch eigene connectoren die sich die SQL-Befehle zusammen bauen, machst Du Dir schon recht viel datenbank unabhängigkeit ohne auf features der datenbank zu verzichten.

hoffe der Text war verständlich.

lg
RR

mbg
Rossegger Robert
mehr fragen mehr wissen

Montag morgen ist die beste Zeit um eine erfolgreiche Woche zu beginnen