Wie realisiert Ihr die Dreischicht-Architektur?

dbausnnd

Aktives Mitglied
Guten Morgen zusammen,

ich mache mir mal wieder Gedanken über die Dreischicht-Architektur. Ich möchte meine Anwendung in den Schichten (von unten nach oben) Datenhaltung, Applikation und Präsentation aufteilen.

Datenhaltung:
Hier habe ich ein Entitätsobjekt, welches einen beispielsweise einen Datensatz in der Datenbank entspricht. Das zugehörigen DAO-Objekt kann das Entitätsobjekt in die Datenbank schreiben, lesen und ändern. Referenzielle Integrität werden in dieser Schicht nicht realisiert. Bedeutet, das eine Referenz lediglich durch die entsprechende ID dargestellt wird.

Applikation.
Die Applikationsschicht beinhaltet Business-Objekte (BO). Diese Business-Objekte sind zu einem hohen Grad identisch mit den Entitägsobjekten. Hier habe ich jedoch die Referenzen aufgelöst. Bedeutet ein BO hat die Referenz auf ein weiteres BO. Die BO werden durch Adapter erstellt. In diesem Adapter ist die Logik enthalten wie ich aus Entitätsobjekten die BO erstellen kann. Beispiel:

Der KundenAuftragAdapter kennt den KundenAuftragDao. Daraus holt er sich eine List von KundenAuftragEntity. Aus dieser Liste wird eine Liste KundenAuftragBo erstellt, in der eine Referenz auf das KundenBo Objekt enthalten ist.
Präsentation
Die Präsentationsschicht ist für meine jetzigen Überlegungen nicht von Belang.


Ich mache mir in regelmäßigen Abständen Gedanken über die Sinnhaftigkeit. Dabei überlege ich ob ich die Objekte in meiner Anwendung generell als BO darstelle. Dementsprechend die Schichten Datenhaltung und Applikation nicht trenne. Mit ist durchaus bewusst, dass es von der Anwendung abhängig ist ob die Dreischicht-Architektur sinnvoll ist oder nicht.

Meine Frage wäre, wie Ihr eine Aufteilung der Schichten durchführt. Solltet Ihr nicht nach der Dreischicht Architektur vorgehen würde mich euer Ansatz auch interessieren.

Gruß

dbausnnd
 

kiwara

Aktives Mitglied
Also so wie du es erklärt hast halte ich es auch nur für eine unnötige Redundanz und Schreibarbeit.

Ich würde es so lösen, dass deine Application classes gleichzeitig fürs Speichern verwendet werden und eben die Klassen der Datenhaltung nur für das OR-Mapping zuständig sind.
 

dbausnnd

Aktives Mitglied
@kiwara
Da hast du natürlich recht. Es ist viel Schreibarbeit. Dadurch sind die Schichten von einander unabhängig. Bei einer Änderung der Datenbank wird lediglich ein neues DAO Objekt benötigt. Wenn die Entität sich ändert, wird ein neues Entitätsobjekt, ein neuer Dao und ein neuer Adapter benötigt. Nach oben ändert sich nichts.

@VfL_Freak
Bei dem Ansatz in dem Link gibt es praktisch kein Entitätsobjekt. In der kompletten Applikation wird mit BO´s gearbeitet. Das DAO Objekt übersetzt das BO Objekt in die Entität. Ist auch ein interessanter Ansatz, der auf jedenfall weniger Schreibarbeit bedeutet.
 

dbausnnd

Aktives Mitglied
Standardmäßig natürlich nicht. Das muss es auch nicht zwangsläufig. Wenn ich Daten einer externen Software auslese und sich diese ändert, kann ich über geringfügige Erweiterung (neuer Dao und neue Entität) die Daten aus der neuen Software lesen. Dort kann es sogar sein das die Daten in unterschiedlichen Datenbanktabellen enthalten ist. Das wäre kein Problem.
 

thecain

Top Contributor
Mehrere verschiedene Klassen für die Datanhaltung macht meiner Erfahrung nach selten Sinn.

Wenn ich am Entity Object was ändere, will ich das zu 99% dann auch in der View irgendwie anzeigen. Vice versa.

Es mag Gründe geben, das unter gewissen Umständen zu trennen, aber meist ist es unnötig.
 

Thallius

Top Contributor
Mehrere verschiedene Klassen für die Datanhaltung macht meiner Erfahrung nach selten Sinn.

Wenn ich am Entity Object was ändere, will ich das zu 99% dann auch in der View irgendwie anzeigen. Vice versa.

Es mag Gründe geben, das unter gewissen Umständen zu trennen, aber meist ist es unnötig.

Dann hast du bisher aber immer nur an sehr kleinen Projekten gearbeitet.

Gruß

Claus
 

dbausnnd

Aktives Mitglied
@thecain
IN meiner Umgebung sind in der Entitätsklassen Informationen bzgl des Zugriffs auf die Daten. Bei einer Änderung dieser Informationen muss ich die Entitägsklasse ändern. Ich will die Klassen nicht ändern sondern erweitern. Daher verwende ich momentan neben der Entitäg auch ein BO. Vielleicht kannst du mir Details zu der von dir bevorzugten Lösung geben?!?

@claus
Würde mich freuen, wenn du die von dir verwendete Methode ein wenig beschreiben könntest. :D
 

Thallius

Top Contributor
Ich arbeite in der Regel mit einem quasi vier Schichten Modell. Die Entität ist die datenhaltende klasse. Dann gibt es eine Daten beschaffende klasse. Nennen wir sie LoaderKlasse und dazu dann den eigentlich Controller und das zugehörige View. Die Entität hat dabei kaum funktionelle Methoden außer Eventuell transformierende Aufgaben um die Daten in vom Controller benötigte Formate zu bringen. Das ist aber auch immer abzuwägen ob diese Methoden in der datenklasse oder im Controller besser aufgehoben sind. Durch das extrahieren der Datenbeschaffung kann ich relativ einfach eine Entität aus anderen Quellen befüllen falls das notwendig wird. Dadurch ändert sich dann nichts an der eintät selber. Auch kann ich die Entität erweitern und die neuen Attribute durch einen anderen Loader befüllen lassen sollte der alte Loader nicht so ohne weiteres umstellbar sein. Ich kann Entität dann auch durch beliebig viele Loader befüllen lassen, was u.U. Zu einem wesentlich übersichtlicherem Code führt als wenn ich irgendwann einen Eierlegenden-Wollmilchsau-Loader habe den keiner mehr warten kann.

Gruß

Claus
 

AndiE

Top Contributor
Ich habe so meine Schwierigkeiten bei dem, was ihr hier schreibt. Wenn ich mal als Usestory annehme, dass für einen Kunden eine Anzahl Produkte zu einer Rechnung zusammengestellt werden, dann muss der Nutzer für Kunden und Produkte jeweils aus einer Anzahl Objekte genau ein Objekt, das aktuelle, auswählen. Und das bei Produkten sogar mehrmals. Für mich würde dann das DAO an die Tabelle angehängt sein, aber eben mit zwei BO verbunden sein, der Sammlung und dem aktuellen Objekt. Wenn ich nun davon ausgehe, dass ich die Sammlung als Liste und das ausgewählte Objekt als Formular darstelle, habe ich schon die Schichten. Ich finde, die Schichten ergeben sich wie von selbst, wenn ich annehme, dass ich die gleiche Funktionalität unterschiedlich ausführe. So kann ich ja z.B. die Präsentation als GUI oder als dynamische Webseite gestalten, und auf der anderen Seite ja auch statt der Datenbank die Serialisierung nutzen.

Mich würde mal interessieren, wieso ihr nur ein BO an das DAO hängt.
 

dbausnnd

Aktives Mitglied
Die Vierte SChicht verstehe ich jetzt nicht ganz. Die Datenklasse sowie der Loader sind teil der Datenhaltung. Dein Controller ist die Applikationsschicht und das View die Präsentation. Oder ist aus deiner sicht die DAtenhaltung und der Loader auch getrennt?

Das von dir skizzierte Szenario ist ähnlich dem von mir. Ich trenne nur die Datenobjekte der Datenhaltung von den anderen beiden Schichten. Zwar benötige ich dadurch einen Adapter der die Konvertierung durchführt, ich habe aber die Flexibilität das ich die Entität tauschen kann.
 

dbausnnd

Aktives Mitglied
@AndiE
In meiner Variante hängt ein BO nicht an einem DAO. Der DAO liest die DAten aus der Quelle und erzeugt eine Enität oder eine Liste von Entitäten. Diese Entitäten werden durch den Adapter in das BO konvertiert. Das BO wird in der Applikation und in der Präsentation verwendet. Für jedes Element (Bspw. Tabelle) gibt es eine Entitä, ein DAO (oder ein GenericDao für alle Tabellen) und ein BO.

In deiner Ausführung sprichst du von einem Formular. Was meinst du damit genau. Deine GUI?
 

AndiE

Top Contributor
Nein. Im obigen Fall kann der Benutzer aus einer Liste einen Kunden auswählen. Dazu stehen dem Benutzer nur wenige Datenfelder in der Liste zur Verfügung. Wählt der Benutzer einen Kunden an, wechselt die Ansicht und der Benutzer erhält ein Formular mit den Kundendaten, wie Adresse, Ansprechpartner und Telefonnummer. Von hier aus wird zu einer Rechnungsliste verlinkt, die auch nur Rechnungsdatum, Rechnungsnummer und Betrag anzeigt. Wenn der Benutzer hier eine Rechnung auswählt, werden die Einzelheiten zur Rechnung angezeigt. an die Tabelle Rechnung ist also ein Objekt verdrahtet, das die Liste der Rechnungen bereitstellt. Die Liste nutzt die Präsentationsschicht dann zur Anzeige. Klickt der Benutzer auf einen Eintrag in der Präsentationsschicht, müssen die Daten des angeklickten Objektes aus der Datenbank geholt werden, um sie dann anzeigen zu können. Dazu muss dann ein Objekt erstellt werden, das nur einen Datensatz präsentiert.
 

Ähnliche Java Themen

Neue Themen


Oben