Ich brauche wirklich eine ehrliche, nachdenkliche Debatte über die Vorzüge des derzeit akzeptierten Paradigmas für das Design von Unternehmensanwendungen .
Ich bin nicht davon überzeugt, dass Entitätsobjekte existieren sollten.
Mit Entitätsobjekten meine ich die typischen Dinge, die wir für unsere Anwendungen erstellen, wie "Person", "Konto", "Bestellung" usw.
Meine aktuelle Designphilosophie lautet:
- Der gesamte Datenbankzugriff muss über gespeicherte Prozeduren erfolgen.
- Wenn Sie Daten benötigen, rufen Sie eine gespeicherte Prozedur auf und iterieren Sie über einen SqlDataReader oder die Zeilen in einer DataTable
(Hinweis: Ich habe auch Unternehmensanwendungen mit Java EE erstellt. Java-Leute ersetzen bitte meine .NET-Beispiele durch das Äquivalent.)
Ich bin kein Anti-OO. Ich schreibe viele Klassen für verschiedene Zwecke, nur keine Entitäten. Ich gebe zu, dass ein großer Teil der Klassen, die ich schreibe, statische Hilfsklassen sind.
Ich baue kein Spielzeug. Ich spreche von großen Transaktionsanwendungen mit hohem Volumen, die auf mehreren Computern bereitgestellt werden. Webanwendungen, Windows-Dienste, Webdienste, B2B-Interaktion, wie Sie es nennen.
Ich habe OR Mappers verwendet. Ich habe ein paar geschrieben. Ich habe den Java EE-Stack, CSLA und einige andere Entsprechungen verwendet. Ich habe sie nicht nur verwendet, sondern diese Anwendungen in Produktionsumgebungen aktiv entwickelt und gewartet.
Ich bin zu dem kampferprobten Schluss gekommen, dass Entitätsobjekte uns in die Quere kommen und unser Leben ohne sie so viel einfacher wäre.
Betrachten Sie dieses einfache Beispiel: Sie erhalten einen Supportanruf zu einer bestimmten Seite in Ihrer Anwendung, die nicht ordnungsgemäß funktioniert. Möglicherweise wird eines der Felder nicht so beibehalten, wie es sein sollte. Bei meinem Modell öffnet der Entwickler, der das Problem gefunden hat, genau 3 Dateien . Eine ASPX-, eine ASPX.CS- und eine SQL-Datei mit der gespeicherten Prozedur. Die Lösung des Problems, bei dem es sich möglicherweise um einen fehlenden Parameter für den Aufruf der gespeicherten Prozedur handelt, dauert nur wenige Minuten. Bei jedem Entitätsmodell wird der Debugger jedoch immer gestartet, der Code wird schrittweise durchlaufen, und möglicherweise werden 15 bis 20 Dateien in Visual Studio geöffnet. Als Sie an den unteren Rand des Stapels getreten sind, haben Sie vergessen, wo Sie angefangen haben. Wir können nur so viele Dinge gleichzeitig im Kopf behalten. Software ist unglaublich komplex, ohne unnötige Ebenen hinzuzufügen.
Entwicklungskomplexität und Fehlerbehebung sind nur eine Seite meines Problems.
Lassen Sie uns nun über die Skalierbarkeit sprechen.
Ist Entwicklern klar, dass sie jedes Mal, wenn sie Code schreiben oder ändern, der mit der Datenbank interagiert, eine gründliche Analyse der genauen Auswirkungen auf die Datenbank durchführen müssen? Und nicht nur die Entwicklungskopie, ich meine eine Nachahmung der Produktion. Sie können also sehen, dass die zusätzliche Spalte, die Sie jetzt für Ihr Objekt benötigen, den aktuellen Abfrageplan ungültig gemacht hat und ein Bericht, der in 1 Sekunde ausgeführt wurde, jetzt nur noch 2 Minuten dauert weil Sie der Auswahlliste eine einzelne Spalte hinzugefügt haben? Und es stellt sich heraus, dass der Index, den Sie jetzt benötigen, so groß ist, dass der DBA das physische Layout Ihrer Dateien ändern muss?
Wenn Sie zulassen, dass Benutzer mit einer Abstraktion zu weit vom physischen Datenspeicher entfernt sind, verursachen sie Chaos mit einer Anwendung, die skaliert werden muss.
Ich bin kein Eiferer. Ich kann überzeugt sein, wenn ich falsch liege, und vielleicht bin ich es auch, da es einen so starken Druck auf Linq zu SQL, ADO.NET EF, Hibernate, Java EE usw. gibt. Bitte denken Sie über Ihre Antworten nach, wenn mir etwas fehlt Ich möchte wirklich wissen, was es ist und warum ich mein Denken ändern sollte.
[Bearbeiten]
Es sieht so aus, als ob diese Frage plötzlich wieder aktiv ist. Nachdem wir nun die neue Kommentarfunktion haben, habe ich mehrere Antworten direkt kommentiert. Vielen Dank für die Antworten, ich denke, das ist eine gesunde Diskussion.
Ich hätte wahrscheinlich klarer sagen sollen, dass ich über Unternehmensanwendungen spreche. Ich kann beispielsweise ein Spiel, das auf dem Desktop einer anderen Person ausgeführt wird, oder eine mobile App wirklich nicht kommentieren.
Eine Sache muss ich hier oben als Antwort auf mehrere ähnliche Antworten anführen: Orthogonalität und Trennung von Bedenken werden oft als Gründe für Entity / ORM angeführt. Gespeicherte Prozeduren sind für mich das beste Beispiel für die Trennung von Bedenken, die mir einfallen. Wenn Sie allen anderen Zugriff auf die Datenbank außer über gespeicherte Prozeduren nicht zulassen, können Sie theoretisch Ihr gesamtes Datenmodell neu gestalten und keinen Code beschädigen, solange Sie die Ein- und Ausgaben der gespeicherten Prozeduren beibehalten. Sie sind ein perfektes Beispiel für die vertragliche Programmierung (nur solange Sie "select *" vermeiden und die Ergebnismengen dokumentieren).
Fragen Sie jemanden, der schon lange in der Branche tätig ist und mit langlebigen Anwendungen gearbeitet hat: Wie viele Anwendungs- und UI-Ebenen sind gekommen und gegangen, während eine Datenbank weiterlebt? Wie schwierig ist es, eine Datenbank zu optimieren und umzugestalten, wenn 4 oder 5 verschiedene Persistenzschichten SQL generieren, um auf die Daten zuzugreifen? Du kannst nichts ändern! ORMs oder Code, der SQL generiert, sperren Ihre Datenbank in Stein .
Antworten:
Ich denke, es kommt darauf an, wie kompliziert die "Logik" der Anwendung ist und wo Sie sie implementiert haben. Wenn sich Ihre gesamte Logik in gespeicherten Prozeduren befindet und Ihre Anwendung diese Prozeduren nur aufruft und die Ergebnisse anzeigt, ist das Entwickeln von Entitätsobjekten in der Tat Zeitverschwendung. Aber für eine Anwendung, in der die Objekte reichhaltige Interaktionen miteinander haben und die Datenbank nur ein Persistenzmechanismus ist, kann es von Wert sein, diese Objekte zu haben.
Ich würde also sagen, dass es keine einheitliche Antwort gibt. Entwickler müssen sich bewusst sein, dass der Versuch, zu OO zu sein, manchmal mehr Probleme verursachen als lösen kann.
quelle
Die Theorie besagt, dass hochkohäsive, lose gekoppelte Implementierungen der Weg in die Zukunft sind.
Ich nehme an, Sie stellen diesen Ansatz in Frage, nämlich die Trennung von Bedenken.
Sollte meine aspx.cs-Datei mit der Datenbank interagieren, einen Sproc aufrufen und IDataReader verstehen?
In einer Teamumgebung, insbesondere wenn weniger technische Mitarbeiter mit dem Aspx-Teil der Anwendung befasst sind, müssen diese Personen dieses Zeug nicht "anfassen" können.
Das Trennen meiner Domain von meiner Datenbank schützt mich vor strukturellen Änderungen in der Datenbank, sicherlich eine gute Sache? Sicher, die Wirksamkeit der Datenbank ist absolut wichtig. Lassen Sie also jemanden, der in diesen Dingen am besten ist, an einem Ort mit diesen Dingen umgehen, ohne den Rest des Systems so wenig wie möglich zu beeinträchtigen.
Wenn ich Ihren Ansatz nicht falsch verstehe, kann eine strukturelle Änderung in der Datenbank einen großen Einfluss auf die Oberfläche Ihrer Anwendung haben. Ich sehe, dass diese Trennung von Bedenken es mir und meinem Team ermöglicht, dies zu minimieren. Auch jedes neue Mitglied des Teams sollte diesen Ansatz besser verstehen.
Außerdem scheint Ihr Ansatz die Geschäftslogik Ihrer Anwendung zu befürworten, die sich in Ihrer Datenbank befindet. Das fühlt sich für mich falsch an. SQL ist wirklich gut darin, Daten abzufragen und imho keine Geschäftslogik auszudrücken.
Interessanter Gedanke, obwohl es sich einen Schritt von SQL in der Aspx entfernt anfühlt, was mich aus meinen schlechten alten unstrukturierten Asp-Tagen mit Furcht erfüllt.
quelle
Ein Grund: Trennen Sie Ihr Domain-Modell von Ihrem Datenbankmodell.
Ich verwende Test Driven Development, also schreibe ich zuerst meine UI- und Modellebenen und die Datenebene wird verspottet, sodass die Benutzeroberfläche und das Modell um domänenspezifische Objekte herum aufgebaut werden. Später ordne ich diese Objekte der von mir verwendeten Technologie zu die die Datenschicht. Es ist eine schlechte Idee, die Datenbankstruktur das Design Ihrer Anwendung bestimmen zu lassen. Wenn möglich, schreiben Sie zuerst die App und lassen Sie dies die Struktur Ihrer Datenbank beeinflussen, nicht umgekehrt.
quelle
Für mich läuft es darauf hinaus, dass meine Anwendung sich nicht mit der Speicherung der Daten befasst. Ich werde wahrscheinlich dafür geschlagen, dass ich das sage ... aber Ihre Anwendung sind nicht Ihre Daten, Daten sind ein Artefakt der Anwendung. Ich möchte, dass meine Anwendung in Bezug auf Kunden, Bestellungen und Artikel denkt, nicht in Bezug auf eine Technologie wie DataSets, DataTables und DataRows ... denn wer weiß, wie lange diese noch verfügbar sein werden.
Ich bin damit einverstanden, dass es immer ein gewisses Maß an Kopplung gibt, aber ich bevorzuge, dass diese Kopplung eher nach oben als nach unten reicht. Ich kann die Äste und Blätter eines Baumes leichter zwicken, als ich seinen Stamm verändern kann.
Ich neige dazu, Sprocs für die Berichterstellung zu reservieren, da die Abfragen tendenziell etwas unangenehmer werden als der allgemeine Datenzugriff der Anwendungen.
Ich neige auch dazu zu denken, dass bei einem ordnungsgemäßen Komponententest in diesem Szenario eine Spalte, die nicht beibehalten wird, wahrscheinlich kein Problem darstellt.
quelle
Eric, du bist tot auf. Für jede wirklich skalierbare / leicht zu wartende / robuste Anwendung besteht die einzige wirkliche Antwort darin, auf den gesamten Müll zu verzichten und sich an die Grundlagen zu halten.
Ich habe mit meiner Karriere einen ähnlichen Weg eingeschlagen und bin zu den gleichen Ergebnissen gekommen. Natürlich gelten wir als Ketzer und sehen lustig aus. Aber meine Sachen funktionieren und funktionieren gut.
Jede Codezeile sollte mit Argwohn betrachtet werden.
quelle
Ich möchte mit einem ähnlichen Beispiel wie dem von Ihnen vorgeschlagenen antworten.
In meiner Firma musste ich einen einfachen CRUD-Bereich für Produkte erstellen, ich baue alle meine Entitäten und eine separate DAL. Später musste ein anderer Entwickler eine verwandte Tabelle ändern und benannte sogar mehrere Felder um. Die einzige Datei, die ich ändern musste, um mein Formular zu aktualisieren, war die DAL für diese Tabelle.
Was (meiner Meinung nach) Entitäten zu einem Projekt bringen, ist:
Ortogonalität: Änderungen in einer Ebene wirken sich möglicherweise nicht auf andere Ebenen aus (wenn Sie eine große Änderung an der Datenbank vornehmen, werden natürlich alle Ebenen erfasst, die meisten kleinen Änderungen jedoch nicht).
Testbarkeit: Sie können Ihre Logik testen, ohne Ihre Datenbank zu berühren. Dies erhöht die Leistung Ihrer Tests (sodass Sie sie häufiger ausführen können).
Trennung von Bedenken: In einem großen Produkt können Sie die Datenbank einem DBA zuweisen und er kann die Hölle daraus optimieren. Weisen Sie das Modell einem Geschäftsexperten zu, der über die erforderlichen Kenntnisse verfügt, um es zu entwerfen. Weisen Sie Entwicklern, die mehr Erfahrung mit Webformularen usw. haben, individuelle Formulare zu.
Abschließend möchte ich hinzufügen, dass die meisten ORM-Mapper gespeicherte Prozeduren unterstützen, da Sie diese verwenden.
Prost.
quelle
Ich denke, Sie könnten zu diesem Thema "mehr abbeißen, als Sie kauen können". Ted Neward war nicht leichtfertig, als er es das " Vietnam der Informatik " nannte.
Eine Sache, die ich Ihnen absolut garantieren kann, ist, dass sie die Sichtweise von niemandem in dieser Angelegenheit ändern wird, wie dies so oft in unzähligen anderen Blogs, Foren, Podcasts usw. bewiesen wurde.
Es ist sicherlich in Ordnung, eine offene Diskussion und Debatte über ein kontroverses Thema zu führen. Es ist nur so oft gemacht worden, dass beide "Seiten" zugestimmt haben, nicht zuzustimmen und einfach mit dem Schreiben von Software fortzufahren.
Wenn Sie auf beiden Seiten weiterlesen möchten, lesen Sie Artikel in Teds Blog, Ayende Rahein, Jimmy Nilson, Scott Bellware, Alt.Net, Stephen Forte, Eric Evans usw.
quelle
@ Dan, sorry, das ist nicht das, wonach ich suche. Ich kenne die Theorie. Ihre Aussage "ist eine sehr schlechte Idee" wird nicht durch ein echtes Beispiel gestützt. Wir versuchen, Software in kürzerer Zeit, mit weniger Mitarbeitern und mit weniger Fehlern zu entwickeln, und wir möchten die Möglichkeit haben, einfach Änderungen vorzunehmen. Mein mehrschichtiges Modell ist meiner Erfahrung nach in allen oben genannten Kategorien negativ. Insbesondere, um das Datenmodell zum letzten Schritt zu machen. Das physikalische Datenmodell muss ab Tag 1 eine wichtige Überlegung sein.
quelle
Ich fand deine Frage wirklich interessant.
Normalerweise benötige ich Entitätsobjekte, um die Geschäftslogik einer Anwendung zu kapseln. Es wäre wirklich kompliziert und unangemessen, diese Logik in die Datenschicht zu verschieben.
Was würden Sie tun, um diese Entitätsobjekte zu vermeiden? Welche Lösung haben Sie vor?
quelle
Entitätsobjekte können das Cache auf der Anwendungsschicht erleichtern. Viel Glück beim Zwischenspeichern eines Datenlesers.
quelle
Wir sollten auch darüber sprechen, was Entitäten wirklich sind. Wenn ich diese Diskussion durchlese, habe ich den Eindruck, dass die meisten Leute hier Entitäten im Sinne eines anämischen Domänenmodells betrachten . Viele Leute betrachten das anämische Domänenmodell als Antimuster!
Rich-Domain-Modelle sind wertvoll. Darum geht es bei Domain Driven Design . Ich persönlich glaube, dass OO ein Weg ist, die Komplexität zu überwinden. Dies bedeutet nicht nur technische Komplexität (wie Datenzugriff, UI-Bindung, Sicherheit ...), sondern auch Komplexität im Geschäftsbereich !
Wenn wir OO-Techniken anwenden können, um unsere Geschäftsprobleme zu analysieren, zu modellieren, zu entwerfen und umzusetzen , ist dies ein enormer Vorteil für die Wartbarkeit und Erweiterbarkeit nicht trivialer Anwendungen!
Es gibt Unterschiede zwischen Ihren Entitäten und Ihren Tabellen. Entitäten sollten Ihr Modell darstellen, Tabellen repräsentieren nur den Datenaspekt Ihres Modells!
Es ist wahr, dass Daten länger leben als Apps, aber betrachten Sie dieses Zitat von David Laribee : Modelle sind für immer ... Daten sind ein glücklicher Nebeneffekt.
Einige weitere Links zu diesem Thema:
Warum Setter und Getter böse sind
Rückgabe von reinem OO
POJO gegen NOJO
Supermodels Teil 2
TDD, Mocks und Design
quelle
Wirklich interessante Frage. Ehrlich gesagt kann ich nicht beweisen, warum Entitäten gut sind. Aber ich kann meine Meinung teilen, warum ich sie mag. Code wie
ist nicht betroffen, woher die Bestellung kam - von der Datenbank, von der Webanforderung, vom Komponententest usw. Diese Methode deklariert expliziter, was genau erforderlich ist, anstatt DataRow zu verwenden und zu dokumentieren, welche Spalten erwartet werden und welche Typen sie haben sollten Sein. Gleiches gilt, wenn Sie es irgendwie als gespeicherte Prozedur implementieren - Sie müssen immer noch die Datensatz-ID darauf drücken, während es in der Datenbank nicht erforderlich sein sollte.
Die Implementierung dieser Methode würde basierend auf der Auftragsabstraktion erfolgen, nicht basierend darauf, wie genau sie in der Datenbank dargestellt wird. Die meisten dieser Operationen, die ich implementiert habe, hängen nicht davon ab, wie diese Daten gespeichert werden. Ich verstehe, dass einige Operationen aus Gründen der Leistung und Skalierbarkeit eine Kopplung mit der DB-Struktur erfordern, nur meiner Erfahrung nach gibt es nicht zu viele davon. Nach meiner Erfahrung reicht es sehr oft aus zu wissen, dass Person .getFirstName () hat, der String zurückgibt, und .getAddress () Adresse zurückgibt und Adresse .getZipCode () usw. hat - und es ist egal, welche Tabellen zum Speichern dieser Daten beteiligt sind .
Wenn Sie sich mit den von Ihnen beschriebenen Problemen befassen müssen, z. B. wenn zusätzliche Spaltenumbrüche die Leistung melden, ist die Datenbank für Ihre Aufgaben ein kritischer Teil, und Sie sollten in der Tat so nah wie möglich daran sein. Während Entitäten einige praktische Abstraktionen bereitstellen können, können sie auch einige wichtige Details verbergen.
Die Skalierbarkeit ist hier ein interessanter Punkt - die meisten Websites, die eine enorme Skalierbarkeit erfordern (wie Facebook, Livejournal, Flickr), verwenden tendenziell einen DB-asketischen Ansatz, wenn DB so selten wie möglich verwendet wird und Skalierbarkeitsprobleme durch Caching gelöst werden, insbesondere durch RAM-Nutzung. http://highscalability.com/ enthält einige interessante Artikel.
quelle
Neben Abstraktion und loser Kopplung gibt es noch andere gute Gründe für Entitätsobjekte. Eines der Dinge, die mir am besten gefallen, ist die starke Eingabe, die Sie mit einem DataReader oder einer DataTable nicht erreichen können. Ein weiterer Grund ist, dass ordnungsgemäße Entitätsklassen den Code besser verwalten können, indem sie erstklassige Konstrukte für domänenspezifische Begriffe verwenden, die jeder, der sich den Code ansieht, wahrscheinlich versteht, anstatt eine Reihe von Zeichenfolgen mit darin verwendeten Feldnamen zum Indizieren einer DataRow. Gespeicherte Prozeduren sind wirklich orthogonal zur Verwendung eines ORM, da viele Mapping-Frameworks Ihnen die Möglichkeit geben, Sprocs zuzuordnen.
Ich würde sprocs + datareaders nicht als Ersatz für ein gutes ORM betrachten. Bei gespeicherten Prozeduren sind Sie immer noch durch die Typensignatur der Prozedur eingeschränkt und eng an diese gekoppelt, die ein anderes Typsystem als den aufrufenden Code verwendet. Gespeicherte Prozeduren können geändert werden, um zusätzliche Optionen und Schemaänderungen zu berücksichtigen. Eine Alternative zu gespeicherten Prozeduren für den Fall, dass sich das Schema ändern kann, ist die Verwendung von Ansichten. Sie können Objekte Ansichten zuordnen und Ansichten dann den zugrunde liegenden Tabellen neu zuordnen, wenn Sie sie ändern.
Ich kann Ihre Abneigung gegen ORMs verstehen, wenn Ihre Erfahrung hauptsächlich aus Java EE und CSLA besteht. Vielleicht möchten Sie einen Blick auf LINQ to SQL werfen, ein sehr leichtes Framework, das in erster Linie eine Eins-zu-Eins-Zuordnung zu den Datenbanktabellen darstellt, aber normalerweise nur eine geringfügige Erweiterung benötigt, damit sie vollständige Geschäftsobjekte sind. LINQ to SQL kann auch Eingabe- und Ausgabeobjekte den Parametern und Ergebnissen gespeicherter Prozeduren zuordnen.
Das ADO.NET-Entitätsframework bietet den zusätzlichen Vorteil, dass Ihre Datenbanktabellen als voneinander erbende Entitätsklassen oder als Spalten aus mehreren Tabellen angezeigt werden können, die zu einer einzigen Entität zusammengefasst sind. Wenn Sie das Schema ändern müssen, können Sie die Zuordnung vom konzeptionellen Modell zum Speicherschema ändern, ohne den tatsächlichen Anwendungscode zu ändern. Auch hier können gespeicherte Prozeduren verwendet werden.
Ich denke, dass mehr IT-Projekte in Unternehmen aufgrund der Nichtwartbarkeit des Codes oder der schlechten Entwicklerproduktivität (die beispielsweise durch Kontextwechsel zwischen Sproc-Writing und App-Writing auftreten kann) scheitern als Skalierbarkeitsprobleme einer Anwendung.
quelle
Ich möchte auch zu Dans Antwort hinzufügen, dass durch die Trennung beider Modelle Ihre Anwendung auf verschiedenen Datenbankservern oder sogar Datenbankmodellen ausgeführt werden kann.
quelle
Was ist, wenn Sie Ihre App skalieren müssen, indem Sie mehr als einen Webserver ausgleichen? Sie können die vollständige App auf allen Webservern installieren. Eine bessere Lösung besteht jedoch darin, die Webserver mit einem Anwendungsserver kommunizieren zu lassen.
Wenn es jedoch keine Entitätsobjekte gibt, haben sie nicht viel zu erzählen.
Ich sage nicht, dass Sie keine Monolithen schreiben sollten, wenn es sich um eine einfache, interne Anwendung mit kurzer Lebensdauer handelt. Aber sobald es mäßig komplex wird oder eine beträchtliche Zeit dauern sollte, müssen Sie wirklich über ein gutes Design nachdenken.
Dies spart Zeit bei der Wartung.
Indem Sie die Anwendungslogik von der Präsentationslogik und dem Datenzugriff trennen und DTOs zwischen ihnen übergeben, entkoppeln Sie sie. Ermöglichen, dass sie sich unabhängig voneinander ändern.
quelle
Vielleicht finden Sie diesen Beitrag auf comp.object interessant.
Ich behaupte nicht, zuzustimmen oder nicht zuzustimmen, aber es ist interessant und (ich denke) relevant für dieses Thema.
quelle
Eine Frage: Wie gehen Sie mit getrennten Anwendungen um, wenn Ihre gesamte Geschäftslogik in der Datenbank eingeschlossen ist?
Bei der Art der Unternehmensanwendung, an der ich interessiert bin, müssen wir uns mit mehreren Standorten befassen. Einige von ihnen müssen in einem getrennten Zustand funktionieren können.
Wenn Ihre Geschäftslogik in einer Domänenschicht gekapselt ist, die einfach in verschiedene Anwendungstypen zu integrieren ist - beispielsweise als
dll
-, kann ich Anwendungen erstellen, die die Geschäftsregeln kennen und diese bei Bedarf lokal anwenden können.Um die Domänenschicht in gespeicherten Prozeduren in der Datenbank zu belassen, müssen Sie sich an einen einzelnen Anwendungstyp halten, der eine permanente Sichtverbindung zur Datenbank benötigt.
Es ist für eine bestimmte Klasse von Umgebungen in Ordnung, deckt jedoch sicherlich nicht das gesamte Spektrum der Unternehmensanwendungen ab .
quelle
@jdecuyper, eine Maxime, die ich mir oft wiederhole, lautet: "Wenn sich Ihre Geschäftslogik nicht in Ihrer Datenbank befindet, ist dies nur eine Empfehlung." Ich denke, Paul Nielson hat das in einem seiner Bücher gesagt. Anwendungsebenen und Benutzeroberfläche kommen und gehen, aber Daten leben normalerweise sehr lange.
Wie vermeide ich Entitätsobjekte? Meistens gespeicherte Prozeduren. Ich gebe auch frei zu, dass Geschäftslogik dazu neigt, alle Ebenen in einer Anwendung zu erreichen, unabhängig davon, ob Sie dies beabsichtigen oder nicht. Ein gewisses Maß an Kopplung ist inhärent und unvermeidbar.
quelle
Ich habe in letzter Zeit viel über dasselbe nachgedacht. Ich war eine Zeit lang ein starker Benutzer von CSLA, und ich liebe die Reinheit zu sagen, dass "Ihre gesamte Geschäftslogik (oder zumindest so viel wie vernünftigerweise möglich) in Geschäftseinheiten eingekapselt ist".
Ich habe gesehen, dass das Geschäftsentitätsmodell in Fällen, in denen sich das Design der Datenbank von der Art und Weise unterscheidet, wie Sie mit den Daten arbeiten, viel Wert bietet, wie dies bei vielen Unternehmenssoftware der Fall ist.
Beispielsweise kann die Idee eines "Kunden" aus einem Hauptdatensatz in einer Kundentabelle bestehen, kombiniert mit allen Bestellungen, die der Kunde aufgegeben hat, sowie allen Mitarbeitern des Kunden und ihren Kontaktinformationen und einigen Eigenschaften von Ein Kunde und seine Kinder können anhand von Nachschlagetabellen ermittelt werden. Aus entwicklungspolitischer Sicht ist es sehr schön, mit dem Kunden als eine Einheit zusammenarbeiten zu können, da das Konzept des Kunden aus geschäftlicher Sicht all diese Dinge enthält und die Beziehungen in der Datenbank möglicherweise erzwungen werden oder nicht.
Ich schätze zwar das Zitat "Wenn Ihre Geschäftsregel nicht in Ihrer Datenbank enthalten ist, ist es nur ein Vorschlag", glaube ich aber auch, dass Sie die Datenbank nicht zur Durchsetzung von Geschäftsregeln entwerfen sollten, sondern sie so gestalten sollten, dass sie effizient, schnell und normalisiert ist .
Das heißt, wie andere oben angemerkt haben, gibt es kein "perfektes Design", das Werkzeug muss zum Job passen. Die Verwendung von Geschäftsentitäten kann jedoch bei der Wartung und Produktivität sehr hilfreich sein, da Sie wissen, wo Sie die Geschäftslogik ändern müssen, und Objekte reale Konzepte auf intuitive Weise modellieren können.
quelle
Eric,
Niemand hindert Sie daran, den gewünschten Rahmen / Ansatz zu wählen. Wenn Sie den Pfad "datengesteuerte / gespeicherte Prozeduren" einschlagen möchten, dann machen Sie es auf jeden Fall! Vor allem, wenn es Ihnen wirklich hilft, Ihre Anwendungen pünktlich und pünktlich zu liefern.
Die Einschränkung ist (eine Kehrseite Ihrer Frage), dass ALLE Ihre Geschäftsregeln auf gespeicherten Prozeduren basieren sollten und Ihre Anwendung nichts weiter als ein Thin Client ist.
Davon abgesehen gelten dieselben Regeln, wenn Sie Ihre Bewerbung in OOP ausführen: Seien Sie konsistent. Folgen OOP die Grundsätze und die Einheit umfasst das Erstellen Objekte Ihrer Domain - Modelle darzustellen.
Die einzige wirkliche Regel ist hier das Wort Konsistenz . Niemand hindert Sie daran, DB-zentriert zu werden. Niemand hindert Sie daran, strukturierte (auch funktionale / prozedurale) Programme der alten Schule durchzuführen. Zur Hölle, niemand hindert jemanden daran, Code im COBOL-Stil zu erstellen. ABER eine Anwendung muss auf diesem Weg sehr, sehr konsistent sein, wenn sie einen gewissen Erfolg erzielen möchte.
quelle
Ich bin mir wirklich nicht sicher, was Sie als "Unternehmensanwendungen" betrachten. Ich habe jedoch den Eindruck, dass Sie es als interne Anwendung definieren, bei der das RDBMS in Stein gemeißelt ist und das System nicht mit anderen internen oder externen Systemen interoperabel sein muss.
Was wäre, wenn Sie eine Datenbank mit 100 Tabellen hätten, die 4 gespeicherten Prozeduren für jede Tabelle entspricht, nur für grundlegende CRUD-Operationen, dh 400 gespeicherte Prozeduren, die gepflegt werden müssen und nicht stark typisiert sind, daher Tippfehler ausgesetzt sind und nicht Unit-getestet werden können . Was passiert, wenn Sie einen neuen CTO erhalten, der Open Source Evangelist ist und das RDBMS von SQL Server auf MySql ändern möchte?
Heutzutage gibt es eine Menge Software, unabhängig davon, ob Unternehmensanwendungen oder -produkte SOA verwenden und einige Anforderungen für die Bereitstellung von Webdiensten haben, zumindest die Software, an der ich beteiligt bin und war. Mit Ihrem Ansatz würden Sie am Ende eine serialisierte Datentabelle oder DataRows verfügbar machen. Dies kann nun als akzeptabel angesehen werden, wenn der Client garantiert .NET und in einem internen Netzwerk ist. Wenn der Client jedoch nicht bekannt ist, sollten Sie sich bemühen, eine intuitive API zu entwerfen, und in den meisten Fällen möchten Sie das vollständige Datenbankschema nicht verfügbar machen. Ich würde einem Java-Entwickler sicherlich nicht erklären wollen, was eine DataTable ist und wie man sie verwendet. Es gibt auch die Berücksichtigung von Bandbreite und Nutzlastgröße und serialisierten DataTables, DataSets sind sehr schwer.
Es gibt keine Silberkugel beim Software-Design und es hängt wirklich davon ab, wo die Prioritäten liegen. Für mich liegt es in Unit Testable-Code und lose gekoppelten Komponenten, die von jedem Kunden problemlos verbraucht werden können.
nur meine 2 Cent
quelle
Ich möchte dem Problem der Entfernung zwischen OO und RDB einen anderen Blickwinkel geben: die Geschichte.
Jede Software hat ein Realitätsmodell, das bis zu einem gewissen Grad eine Abstraktion der Realität ist. Kein Computerprogramm kann alle Komplexitäten der Realität erfassen, und Programme werden nur geschrieben, um eine Reihe von Problemen aus der Realität zu lösen. Daher ist jedes Softwaremodell eine Reduktion der Realität. Manchmal zwingt das Softwaremodell die Realität, sich selbst zu reduzieren. Zum Beispiel, wenn Sie möchten, dass die Autovermietung ein Auto für Sie reserviert, solange es blau ist und Legierungen aufweist, der Betreiber dies jedoch nicht tun kann, da Ihre Anfrage nicht in den Computer passt.
RDB stammt aus einer sehr alten Tradition, Informationen in Tabellen zu schreiben, die als Buchhaltung bezeichnet werden. Die Abrechnung erfolgte auf Papier, dann auf Lochkarten und dann auf Computern. Aber Buchhaltung ist bereits eine Reduktion der Realität. Das Rechnungswesen hat die Menschen gezwungen, seinem System so lange zu folgen, bis es zur Realität geworden ist. Aus diesem Grund ist es relativ einfach, Computersoftware für die Buchhaltung zu erstellen. Die Buchhaltung hatte ihr Informationsmodell, lange bevor der Computer auf den Markt kam.
Angesichts der Bedeutung guter Buchhaltungssysteme und der Akzeptanz, die Sie von Geschäftsführern erhalten, sind diese Systeme sehr weit fortgeschritten. Die Datenbankgrundlagen sind jetzt sehr solide und niemand zögert, wichtige Daten in etwas so Vertrauenswürdigem aufzubewahren.
Ich denke, dass OO mitgekommen sein muss, als die Leute festgestellt haben, dass andere Aspekte der Realität schwieriger zu modellieren sind als das Rechnungswesen (das bereits ein Modell ist). OO ist eine sehr erfolgreiche Idee geworden, aber die Beständigkeit von OO-Daten ist relativ unterentwickelt. RDB / Accounting hat leicht gewonnen, aber OO ist ein viel größeres Feld (im Grunde alles, was nicht Accounting ist).
So viele von uns wollten OO verwenden, aber wir möchten immer noch eine sichere Speicherung unserer Daten. Was kann sicherer sein, als unsere Daten genauso zu speichern wie das angesehene Buchhaltungssystem? Es ist eine verlockende Aussicht, aber wir alle stoßen auf die gleichen Fallstricke. Nur sehr wenige haben sich die Mühe gemacht, an die Persistenz von OO zu denken, verglichen mit den massiven Anstrengungen der RDB-Branche, die von der Tradition und Position des Rechnungswesens profitiert hat.
Prevayler und db4o sind einige Vorschläge, ich bin sicher, es gibt andere, von denen ich noch nichts gehört habe, aber keiner scheint die halbe Presse als Winterschlaf zu bekommen.
Das Speichern Ihrer Objekte in guten alten Dateien scheint für Mehrbenutzeranwendungen und insbesondere für Webanwendungen nicht einmal ernst genommen zu werden.
In meinem täglichen Kampf, die Kluft zwischen OO und RDB zu schließen, benutze ich OO so oft wie möglich, versuche aber, die Vererbung auf ein Minimum zu beschränken. Ich benutze nicht oft SPs. Ich werde das erweiterte Abfragematerial nur in Aspekten verwenden, die wie Buchhaltung aussehen.
Ich werde glücklich überrascht sein, wenn der Abgrund endgültig geschlossen ist. Ich denke, die Lösung wird kommen, wenn Oracle so etwas wie "Oracle Object Instance Base" startet. Um wirklich zu verstehen, muss es einen beruhigenden Namen haben.
quelle
Im Moment nicht viel Zeit, aber auf Anhieb ...
Mit dem Entitätsmodell können Sie der Datenbank (und anderen möglichen Systemen) eine konsistente Schnittstelle zuweisen, die über die Möglichkeiten einer Schnittstelle für gespeicherte Prozeduren hinausgeht. Durch die Verwendung unternehmensweiter Geschäftsmodelle können Sie sicherstellen, dass alle Anwendungen die Daten konsistent beeinflussen, was SEHR wichtig ist. Andernfalls erhalten Sie schlechte Daten, was einfach nur böse ist.
Wenn Sie nur eine Anwendung haben, haben Sie nicht wirklich ein "Enterprise" -System, unabhängig davon, wie groß diese Anwendung oder Ihre Daten sind. In diesem Fall können Sie einen ähnlichen Ansatz verwenden, über den Sie sprechen. Seien Sie sich nur der Arbeit bewusst, die erforderlich ist, wenn Sie Ihre Systeme in Zukunft erweitern möchten.
Hier sind einige Dinge, die Sie beachten sollten (IMO):
quelle
Manchmal sind Ihre Anwendung und Ihre Datenschicht nicht so eng miteinander verbunden. Beispielsweise haben Sie möglicherweise eine telefonische Abrechnungsanwendung. Sie erstellen später eine separate Anwendung, die die Telefonnutzung überwacht, um a) besser für Sie zu werben, b) Ihren Telefonplan zu optimieren.
Diese Anwendungen haben unterschiedliche Bedenken und Datenanforderungen (selbst wenn die Daten aus derselben Datenbank stammen), sie würden unterschiedliche Designs steuern. Ihre Codebasis kann ein absolutes Chaos (in beiden Anwendungen) und einen Albtraum verursachen, wenn Sie die Datenbank den Code steuern lassen.
quelle
Anwendungen, deren Domänenlogik von der Datenspeicherlogik getrennt ist, können an jede Art von Datenquelle (Datenbank oder anderweitig) oder Benutzeroberfläche (Web oder Windows (oder Linux usw.)) angepasst werden.
Sie stecken ziemlich fest in Ihrer Datenbank, was nicht schlecht ist, wenn Sie mit einem Unternehmen zusammenarbeiten, das mit dem aktuellen Datenbanksystem, das Sie verwenden, zufrieden ist. Da sich Datenbanken im Laufe der Zeit weiterentwickeln, gibt es möglicherweise ein neues Datenbanksystem, das wirklich ordentlich und neu ist und das Ihr Unternehmen verwenden möchte. Was wäre, wenn sie zu einer Webdienstmethode für den Datenzugriff wechseln wollten (wie dies manchmal bei einer serviceorientierten Architektur der Fall ist)? Möglicherweise müssen Sie Ihre gespeicherten Prozeduren überall portieren.
Außerdem abstrahiert die Domänenlogik die Benutzeroberfläche, was in großen komplexen Systemen mit sich ständig weiterentwickelnden Benutzeroberflächen wichtiger sein kann (insbesondere, wenn ständig nach mehr Kunden gesucht wird).
Auch wenn ich damit einverstanden bin, dass es keine endgültige Antwort auf die Frage der gespeicherten Prozeduren im Vergleich zur Domänenlogik gibt. Ich bin im Domain-Logik-Camp (und ich denke, sie gewinnen mit der Zeit), weil ich glaube, dass ausgefeilte gespeicherte Prozeduren schwieriger zu warten sind als ausgefeilte Domain-Logik. Aber das ist eine ganz andere Debatte
quelle
Ich denke, Sie sind es einfach gewohnt, eine bestimmte Art von Anwendung zu schreiben und eine bestimmte Art von Problem zu lösen. Sie scheinen dies aus der Perspektive "Datenbank zuerst" anzugreifen. Es gibt viele Entwickler, bei denen Daten in einer Datenbank gespeichert werden, die Leistung jedoch keine oberste Priorität hat. In vielen Fällen vereinfacht das Platzieren einer Abstraktion über der Persistenzschicht den Code erheblich, und die Leistungskosten sind kein Problem.
Was auch immer Sie tun, es ist nicht OOP. Es ist nicht falsch, es ist einfach nicht OOP und es macht keinen Sinn, Ihre Lösungen auf jedes andere Problem da draußen anzuwenden.
quelle
Interessante Frage. Ein paar Gedanken:
quelle
Gute Frage!
Ein Ansatz, den ich eher mag, besteht darin, ein Iterator / Generator-Objekt zu erstellen, das Instanzen von Objekten ausgibt, die für einen bestimmten Kontext relevant sind. Normalerweise umschließt dieses Objekt einige zugrunde liegende Daten für den Datenbankzugriff, aber das muss ich nicht wissen, wenn ich es verwende.
Beispielsweise,
Ich habe festgestellt, dass dies gut funktioniert, wenn ich einen großen Datensatz zum Bearbeiten habe, und wenn es richtig gemacht wird, erhalte ich kleine, vorübergehende Objekte, die relativ einfach zu testen sind.
Es ist im Grunde ein dünnes Furnier über dem Database Access-Material, aber es gibt mir immer noch die Flexibilität, es zu abstrahieren, wenn ich es brauche.
quelle
Die Objekte in meinen Apps beziehen sich in der Regel eins zu eins auf die Datenbank. Ich finde jedoch, dass die Verwendung von Linq To Sql anstelle von Sprocs das Schreiben komplizierter Abfragen erheblich erleichtert, insbesondere wenn sie mithilfe der verzögerten Ausführung erstellt werden können. zB von r in Images.User.Ratings wo usw. Dies erspart mir den Versuch, mehrere Join-Anweisungen in SQL zu erarbeiten, und Skip & Take für das Paging vereinfacht auch den Code, anstatt den row_number & 'over'-Code einbetten zu müssen.
quelle
Warum bei Entitätsobjekten anhalten? Wenn Sie den Wert mit Entitätsobjekten in einer App auf Unternehmensebene nicht sehen, führen Sie Ihren Datenzugriff einfach in einer rein funktionalen / prozeduralen Sprache durch und verbinden Sie ihn mit einer Benutzeroberfläche. Warum nicht einfach alle OO "Flusen" herausschneiden?
quelle