Laden...

Beim Zugriff auf deine Datenbank: Kommunikation über Klassen oder Repositories?

Erstellt von Scholly vor 5 Jahren Letzter Beitrag vor 5 Jahren 1.045 Views
S
Scholly Themenstarter:in
19 Beiträge seit 2013
vor 5 Jahren
Beim Zugriff auf deine Datenbank: Kommunikation über Klassen oder Repositories?

Hallo,

ich habe mal eine Grundsatzfrage zur Objektorientierten Programmierung. Ich arbeite mit WPF

Angenommen ich habe ein Programm das mit verschiedenen Usern arbeitet die jeweils in einer Datenbanktabelle gespeichert sind.
In dem Programm habe ich nun die Klasse "User", hier definiere ich die Eigenschaften, usw.

Jetzt frage ich mich wie macht ihr das in folgenden Fällen:

  1. Man braucht eine Liste mit allen Usern um sie z.B. an die GUI zu binden.
    Von wo aus startet ihr die Abfrage?
    Legt ihr dazu eine extra Klasse "Users" an, die solche übergeordneten Methoden an das Datenbank Interface sendet?
    Wer wandelt die Daten von der Datenbank in die Klasse User um?
    Haltet ihr eine Liste im Speicher die die User enthält?

  2. Wenn am User veränderungen vorgenommen wurden, wie werden die Änderungen an die DB kommuniziert?
    Auch wieder über die "Users"-Klasse? z.B. Users.UpdateUser(User _user)
    Oder kann der einzelne User von sich aus Updates senden?

Vielen Dank für Euren Input

T
2.224 Beiträge seit 2008
vor 5 Jahren

Hier müsste man weit ausholen um dir deine simplen Fragen zu beantworten.
Dazu musst du dich am besten mal in ADO.NET einlesen um den DB Part zu verstehen.

Um diese Funktionen abzubilden nimmst du am besten direkt das Drei-Schichten-Modell

Grundsätzlich stellt man aber erst einmal das Modell, hier eine Klasse User dar.
Diese enthält dann alle Eigenschaften und Informationen über den User.
In dieser Klasse ist aber keine Logik(Methoden) o.ä. vorhanden.
Diese soll eben nur als Datenstruktur dienen.
Diese werden dann in der Definitionsschicht abgelegt, wo eben nur die Modelle definiert sind.

Dann legt man sich die Datenschicht an.
In dieser wird dann vereinfacht gesagt die Datenhaltung umgesetzt.
Diese kennt auch die Definitionsschicht und kann somit auf die Modelle zugreifen.
Entsprechend werden die Informationen aus der User Klasse in die DB geschrieben oder die Userdaten dort abgefragt.

Dazu nimmt man dann entweder ADO.NET mit entsprechenden Providern wie dem Sql* Klassen für den SQL Server von MS oder je nach DB Hersteller eben andere Provider.
Jeder große Datenbankanbieter liefert auch für .NET die passenden Provider Klassen.
Alternativ kann man auch mit OR Mappern arbeiten, die dann die DB Verabeitung übernehmen.
Diese haben aber ihre eigenen Vor- und Nachteile.

dann legt man dooe Anwendungs- oder Businessschicht an.
Diese enthält dann die Anwendungslogik und baut kennt sowohl die Definitionsschicht als auch die Datenschicht.
Entsprechend kann die Anwendungsschicht dann die Modelle erzeugen und an die Datenschicht zum speichern weiterleiten.
Darüber kannst du dann auch deine Daten für deine User abfragen.

Deine UI, egal ob WPF, Winforms oder eine Konsolen Anwendung, kennt dann nur die Definitions- und die Anwendungsschicht.
Somit kann diese eben die Modelle anlegen/verarbeiten aber über die Anwendungsschicht dann auch an die Datenschicht weiterleiten zum speichen/updaten in der DB.

Ist etwas viel und wird vermutlich erst klar, wenn du dich in das Thema eingearbeitet hast.
Aber deine Fragen lassen sich leider nicht so einfach beantworten 😄

Einfaches Code Beispiel wie das dann in deiner Anwendung aussehen kann:


// Definitions.dll
public class User
{
    public string Username { get; set; }

    public string Passwort { get; set; }

    // Weitere Eigenschaften deiner User Klasse
}

// Data.dll, Hat Definitions.dll als Referenz
public class UserDataLayer
{
    public void AddUser(User user)
    {
        // Hier mit ADO.NET die Daten aus dem user Objekt auf die DB Spalten per Insert mappen
    }

    public List<User> ListUser()
    {
        // Hier per Select die User auflisten und mit DataReader auslesen
    }
}

// Application.dll, Hat Data.dll und Definitions.dll als Referenz
public class UserManager
{
    public void AddUser(User user)
    {
        UserDataLayer db = new UserDataLayer();
        db.AddUser(user);
    }

    public List<User> ListUser()
    {
        UserDataLayer db = new UserDataLayer();
        return db.ListUser();
    }
}

// Einfache Konsolen Anwendung, Hat Application.dll und Definitions.dll als Referenz
public class Program
{
    public static void Main(string[] args)
    {
        User user = new User("Benutzername", "Passwort");
        UserManager userManager = new UserManager();
        userManager.AddUser(user);
        List<User> users = userManager.ListUser();

        foreach(User user in users)
        {
             Console.WriteLine(user.Username);
        }
    }
}

T-Virus

Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.

5.658 Beiträge seit 2006
vor 5 Jahren

Hier müsste man weit ausholen um dir deine simplen Fragen zu beantworten.

Deswegen gibt es ja den [Artikel] Drei-Schichten-Architektur

Weeks of programming can save you hours of planning

T
2.224 Beiträge seit 2008
vor 5 Jahren

@MrSparkle
Hab schon zuweit ausgeholt 😕
Aber das sollte klarer sein!

Martin

Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.

S
Scholly Themenstarter:in
19 Beiträge seit 2013
vor 5 Jahren

Erstmal vielen Dank für deine ausführliche Antwort T-Virus.

Ich denke ich verstehe was Du meinst und habe das bei meinen Projekten auch schon instinktiv so in der Art umgesetzt, habe mich aber immer gefragt was wohl der "richtige" weg ist.

Scheinbar hängt das auch vom jeweiligen Projekt ab, aber eine Trennung der Schichten und Verantwortlichkeiten habe ich bisher als immer Vorteilhaft empfunden, allein schon wegen der Nachvollziehbarkeit, vor allem wenn man nach ein paar Wochen zurück kommt und sich neu einlesen muss.

Eine Frage hätte ich da aber noch:
Der UserDataLayer, kommuniziert der direkt mit der Datenbank? In deinem Beispiel sieht es so aus als wenn es für jeden Bereich, z.B. Kunden, Lieferanten, etc. jeweils einen KundenDataLayer, LieferantenDataLayer, usw. gibt die jeweils direkt mit der Datenbank kommunizieren.
In meinen Programmen hab ich immer eine allgemeine (statische/singleton) DatabaseAccess-Klasse geschrieben die den Zugriff auf die Datenbank für alle anderen Manager-Klassen ermöglicht. Diese Klasse stellt z.B. auch die Datenbankverbindung her, gibt Meldungen zurück usw.
Die Methoden sehen dann etwa so aus: DatabaseAccess.FreeWrite(string _command) oder DatabaseAccess.FreeQuery(string _query).

Mein Hintergedanke war die direkte Kommunikation mit der Datenbank von einer separaten Klasse erledigen zu lassen, denn wenn es an der Art wie die Abfragen ausgeführt werden Änderungen geben sollte, dann ist das schnell erledigt.
Damit würde ich nach meinem Verständnis eine 4. Schicht erzeugen. Siehst du das als unnötig an?

5.658 Beiträge seit 2006
vor 5 Jahren

Hi Scholly,

glaube, du solltest wirklich erstmal etwas darüber lesen, und dann statische Implementierungen, mehrere DALs, "separate" Klassen etc. schnell wieder vergessen.
Es gibt das Repository-Pattern und UnitOfWork. Du mußt das Rad nicht neu erfinden.

Weeks of programming can save you hours of planning