Meiner Meinung nach ist das absolut nicht so gemeint. Und es ist eine Verletzung von DRY.
Die Idee ist, dass das Objekt Entität / Domäne in der Mitte so modelliert wird, dass die Domäne so gut und bequem wie möglich dargestellt wird. Es steht im Zentrum von allem und alles kann davon abhängen, da sich die Domain selbst die meiste Zeit nicht ändert.
Wenn Ihre externe Datenbank diese Objekte direkt speichern kann, ist das Zuordnen zu einem anderen Format zum Trennen von Ebenen nicht nur sinnlos, sondern das Erstellen von Duplikaten des Modells, und das ist nicht beabsichtigt.
Zunächst wurde die saubere Architektur unter Berücksichtigung einer anderen typischen Umgebung / eines anderen typischen Szenarios erstellt. Business Server-Anwendungen mit riesigen äußeren Schichten, die ihre eigenen Arten von speziellen Objekten benötigen. Zum Beispiel Datenbanken, die SQLRow
Objekte produzieren und SQLTransactions
im Gegenzug Elemente aktualisieren müssen. Wenn Sie diese in der Mitte verwenden würden, würden Sie die Abhängigkeitsrichtung verletzen, da Ihr Kern von der Datenbank abhängen würde.
Mit einfachen ORMs, die Entitätsobjekte laden und speichern, ist dies nicht der Fall. Sie machen die Zuordnung zwischen ihrer internen SQLRow
und Ihrer Domain. Selbst wenn Sie eine @Entitiy
Anmerkung des ORM in Ihr Domänenobjekt einfügen müssen, würde ich argumentieren, dass dies keine "Erwähnung" der äußeren Schicht bewirkt. Da Anmerkungen nur Metadaten sind, werden sie von keinem Code angezeigt, der nicht speziell danach sucht. Und was noch wichtiger ist, es muss nichts geändert werden, wenn Sie sie entfernen oder durch die Anmerkung einer anderen Datenbank ersetzen.
Wenn Sie dagegen Ihre Domain ändern und all diese Mapper erstellt haben, müssen Sie eine Menge ändern.
Änderung: Oben ist ein wenig vereinfacht und könnte sogar falsch sein. Weil es in einer sauberen Architektur einen Teil gibt, bei dem Sie eine Darstellung pro Ebene erstellen möchten. Dies muss jedoch im Zusammenhang mit der Anwendung gesehen werden.
Und zwar hier https://blog.8thlight.com/uncle-bob/2012/08/13/the-clean-architecture.html
Wichtig ist, dass isolierte, einfache Datenstrukturen über die Grenzen hinweg übertragen werden. Wir möchten keine Entities- oder Database-Zeilen betrügen und weitergeben . Wir möchten nicht, dass die Datenstrukturen Abhängigkeiten aufweisen, die gegen die Abhängigkeitsregel verstoßen.
Das Übergeben von Objekten von der Mitte zu den äußeren Ebenen verstößt nicht gegen die Abhängigkeitsregel, wird jedoch erwähnt. Dies hat aber einen Grund im Rahmen der vorgesehenen Anwendung. Das Weitergeben von Entitäten würde die Anwendungslogik nach außen verschieben. Äußere Ebenen müssten wissen, wie die inneren Objekte zu interpretieren sind, sie müssten effektiv das tun, was innere Ebenen wie die "Anwendungsfall" -Ebene tun sollen.
Außerdem werden Ebenen entkoppelt, sodass Änderungen am Kern nicht unbedingt Änderungen an den äußeren Ebenen erforderlich machen (siehe den Kommentar von SteveCallender). In diesem Zusammenhang ist leicht zu erkennen, wie Objekte genau den Zweck darstellen sollen, für den sie verwendet werden. Außerdem sollten diese Ebenen in Bezug auf Objekte, die speziell für die Zwecke dieser Kommunikation hergestellt wurden, miteinander kommunizieren. Dies kann sogar bedeuten, dass es 3 Darstellungen gibt, 1 in jeder Schicht, 1 für den Transport zwischen Schichten.
Und es gibt https://blog.8thlight.com/uncle-bob/2011/11/22/Clean-Architecture.html mit den folgenden Adressen:
Andere Leute haben befürchtet, dass das Nettoergebnis meines Ratschlags viel doppelter Code und viel rotes Kopieren von Daten von einer Datenstruktur in eine andere über die Ebenen des Systems hinweg sein könnte. Das will ich natürlich auch nicht; und nichts, was ich angedeutet habe, würde unvermeidlich zur Wiederholung von Datenstrukturen und zu übermäßigem Kopieren von Feldern führen.
Diese IMO impliziert, dass einfaches 1: 1-Kopieren von Objekten ein Geruch in der Architektur ist, weil Sie nicht die richtigen Ebenen und / oder Abstraktionen verwenden.
Er erklärt später, wie er sich all das "Kopieren" vorstellt
Sie trennen die Benutzeroberfläche von den Geschäftsregeln, indem Sie einfache Datenstrukturen zwischen den beiden übergeben. Sie lassen Ihre Controller nichts über die Geschäftsregeln wissen. Stattdessen entpacken die Controller das HttpRequest-Objekt in eine einfache Vanille-Datenstruktur und übergeben diese Datenstruktur an ein Interaktionsobjekt, das den Anwendungsfall durch Aufrufen von Geschäftsobjekten implementiert. Der Interaktor sammelt dann die Antwortdaten in einer anderen Vanille-Datenstruktur und leitet sie an die Benutzeroberfläche zurück. Die Ansichten kennen die Geschäftsobjekte nicht. Sie schauen nur in diese Datenstruktur und präsentieren die Antwort.
In dieser Anwendung gibt es einen großen Unterschied zwischen den Darstellungen. Die Daten, die fließen, sind nicht nur die Entitäten. Und dies rechtfertigt und fordert verschiedene Klassen.
Wird jedoch auf eine einfache Android-Anwendung wie einen Fotobetrachter angewendet, bei der die Photo
Entität über 0 Geschäftsregeln verfügt und der "Anwendungsfall", der sich mit ihnen befasst, nahezu nicht vorhanden ist und sich eher mit Caching und Download beschäftigt (dieser Prozess sollte IMO sein) deutlicher dargestellt), beginnt der Punkt, separate Darstellungen eines Fotos zu machen, zu verschwinden. Ich habe sogar das Gefühl, dass das Foto selbst das Datenübertragungsobjekt ist, während die eigentliche Business-Logik-Core-Ebene fehlt.
Es gibt einen Unterschied zwischen "Trennen Sie die Benutzeroberfläche von den Geschäftsregeln, indem Sie einfache Datenstrukturen zwischen den beiden übergeben" und "Wenn Sie ein Foto anzeigen möchten, benennen Sie es unterwegs dreimal um" .
Abgesehen davon ist der Punkt, an dem ich sehe, dass diese Demoanwendungen die saubere Architektur nicht darstellen, dass sie der Trennung von Ebenen zuliebe eine große Betonung beimessen, aber effektiv verbergen, was die Anwendung tut. Das steht im Gegensatz zu dem, was in https://blog.8thlight.com/uncle-bob/2011/09/30/Screaming-Architecture.html gesagt wird - nämlich dass
Die Architektur einer Softwareanwendung schreit nach den Anwendungsfällen der Anwendung
Ich sehe keine Betonung auf die Trennung von Schichten in der reinen Architektur. Es geht um die Abhängigkeitsrichtung und darum, den Kern der Anwendung - Entitäten und Anwendungsfälle - in idealerweise einfachem Java ohne Abhängigkeiten nach außen darzustellen. Es geht nicht so sehr um Abhängigkeiten zu diesem Kern.
Wenn Ihre Anwendung also tatsächlich einen Kern hat, der Geschäftsregeln und Anwendungsfälle darstellt, und / oder verschiedene Personen auf verschiedenen Ebenen arbeiten, trennen Sie diese bitte auf die vorgesehene Weise. Wenn Sie andererseits nur eine einfache App schreiben, übertreiben Sie es nicht. 2 Schichten mit fließenden Grenzen können mehr als genug sein. Ebenen können auch später hinzugefügt werden.
BankAccount
aber mit anwendungsspezifischen Regeln, was Sie mit diesem Konto tun können.@SerializedName
Gson-Anmerkungen in ein Domain-Modell einfügen? Oder würden Sie ein neues Objekt erstellen, das für die Zuordnung der Webantwort zum Domänenmodell verantwortlich ist?Du hast es tatsächlich richtig gemacht. Und es gibt keine Verletzung von DRY, weil Sie SRP akzeptieren.
Zum Beispiel: Sie haben eine Geschäftsmethode createX (String name), dann haben Sie möglicherweise eine Methode createX (String name) in der DAO-Ebene, die innerhalb der Geschäftsmethode aufgerufen wird. Sie haben möglicherweise die gleiche Unterschrift und es gibt möglicherweise nur eine Delegation, aber sie haben unterschiedliche Zwecke. Sie können auch ein createX (String name) im UseCase haben. Auch dann ist es nicht redundant. Damit meine ich: Gleiche Signaturen bedeuten nicht gleiche Semantik. Wählen Sie andere Namen, damit die Semantik klar ist. Wenn Sie sich selbst benennen, hat dies keinerlei Einfluss auf die SRP.
Der UseCase ist für die anwendungsspezifische Logik verantwortlich, das Geschäftsobjekt ist für die anwendungsunabhängige Logik verantwortlich und das DAO ist für das Speichern verantwortlich.
Aufgrund der unterschiedlichen Semantik können alle Schichten ein eigenes Darstellungs- und Kommunikationsmodell haben. Oft sehen Sie "Entitäten" als "Geschäftsobjekte" und oft sehen Sie nicht die Notwendigkeit, sie zu trennen. Bei "großen" Projekten sollte jedoch versucht werden, die Ebenen ordnungsgemäß zu trennen. Je größer das Projekt, desto größer ist die Möglichkeit, dass Sie die unterschiedliche Semantik benötigen, die in verschiedenen Ebenen und Klassen dargestellt wird.
Sie können sich verschiedene Aspekte derselben Semantik vorstellen. Ein User-Objekt muss auf dem Bildschirm angezeigt werden, es hat einige innere Konsistenzregeln und es muss irgendwo gespeichert werden. Jeder Aspekt sollte in einer anderen Klasse (SRP) dargestellt werden. Das Erstellen der Mapper kann schmerzhaft sein. In den meisten Projekten, die ich unter diesen Aspekten bearbeitet habe, wird dies zu einer Klasse zusammengefasst. Dies ist eindeutig eine Verletzung von SRP, aber niemand kümmert sich wirklich darum.
Ich nenne die Anwendung von Clean Architecture und SOLID "nicht sozialverträglich". Ich würde damit arbeiten, wenn ich darf. Momentan darf ich das nicht. Ich warte auf den Moment, in dem wir darüber nachdenken müssen, SOLID ernst zu nehmen.
quelle
Nein, Sie müssen nicht in jeder Ebene Modellklassen erstellen.
Entity (
DATA_LAYER
) - ist eine vollständige oder teilweise Darstellung des Datenbankobjekts.DATA_LAYER
Mapper (
DOMAIN_LAYER
) - ist eigentlich eine Klasse, die Entity in ModelClass konvertiert, für die es verwendet wirdDOMAIN_LAYER
Schauen Sie sich das an: https://github.com/lifedemons/photoviewer
quelle