Betrachten Sie dieses Beispiel:
Ich habe eine Website. Es ermöglicht Benutzern, Beiträge zu verfassen (kann alles sein) und Tags hinzuzufügen, die den Beitrag beschreiben. Im Code habe ich zwei Klassen, die den Beitrag und die Tags darstellen. Nennen wir diese Klassen Post
und Tag
.
Post
kümmert sich um das Erstellen von Posts, das Löschen von Posts, das Aktualisieren von Posts usw.
Tag
kümmert sich um das Erstellen von Tags, das Löschen von Tags, das Aktualisieren von Tags usw.
Es fehlt eine Operation. Das Verknüpfen von Tags mit Posts. Ich habe Probleme damit, wer diese Operation durchführen soll. Es könnte in jede Klasse gleich gut passen.
Einerseits Post
könnte die Klasse eine Funktion haben, die a Tag
als Parameter verwendet und es dann in einer Liste von Tags speichert. Andererseits Tag
könnte die Klasse eine Funktion haben, die a Post
als Parameter verwendet und das Tag
mit dem verknüpft Post
.
Das Obige ist nur ein Beispiel für mein Problem. Ich stoße tatsächlich auf mehrere Klassen, die alle ähnlich sind. Es könnte in beide gleich gut passen. Welche Konventionen oder Designstile gibt es, um dieses Problem zu lösen, ohne die Funktionalität tatsächlich in beide Klassen einzuteilen? Ich gehe davon aus, dass es etwas anderes geben muss, als nur eines auszuwählen?
Vielleicht ist es die richtige Antwort, es in beide Klassen einzuteilen?
quelle
Nein, nicht in beiden! Es sollte an einem Ort sein.
Was ich an Ihrer Frage unangenehm finde, ist die Tatsache, dass Sie sagen "
Post
kümmert sich um das Erstellen von Posts, das Löschen von Posts, das Aktualisieren von Posts" und dasselbe fürTag
. Nun, das ist nicht richtig.Post
kann sich nur um die Aktualisierung kümmern, das gleiche gilt fürTag
. Das Erstellen und Löschen ist die Arbeit einer anderen Person außerhalb vonPost
undTag
(nennen wir es einfachStore
).Gute Verantwortung für
Post
ist "kennt den Autor, den Inhalt und das Datum der letzten Aktualisierung". Gute Verantwortung fürTag
ist "kennt seinen Namen und Zweck (lesen: Beschreibung)". Gute Verantwortung fürStore
ist "kennt alle Beiträge und alle Tags und kann sie hinzufügen, entfernen und durchsuchen".Wenn Sie sich diese drei Teilnehmer ansehen, wer ist am natürlichsten derjenige, der das Wissen über die Post-Tag-Beziehung haben sollte?
(Für mich ist es der Beitrag, es scheint natürlich, dass er "seine Tags kennt"; die umgekehrte Suche (alle Beiträge für einen Tag) scheint die Aufgabe des Geschäfts zu sein; obwohl ich mich möglicherweise irre)
quelle
ConditionalWeakTable
(vorausgesetzt, man hat das Glück, einen Rahmen zu haben, in dem man existiert)?In der Gleichung fehlt ein wichtiges Detail. Warum enthält Tag Post und umgekehrt? Die Antwort auf diese Frage bestimmt die Lösung für jeden gegebenen Satz.
Im Allgemeinen kann ich mir eine ähnliche Situation vorstellen. Eine Box und Inhalt. Eine Box hat Inhalt, daher ist eine Beziehung angemessen. Kann der Inhalt eine Box haben? Klar, eine Box mit einer Box. Eine Box ist Inhalt. IS-A ist jedoch nicht für alle Boxen geeignet. In einem solchen Fall würde ich ein Dekorationsmuster in Betracht ziehen. Auf diese Weise wird eine Box bei Bedarf zur Laufzeit mit Inhalten dekoriert.
Tags können auch Posts haben, aber für mich ist dies keine statische Beziehung. Es könnte sich vielmehr um einen Bericht aller Beiträge handeln, die diesen Tag haben. In diesem Fall handelt es sich um eine neue Entität, nicht um eine.
quelle
Während theoretisch solche Dinge in beide Richtungen gehen können, passt in der Praxis, wenn Sie zur Implementierung kommen, eine Richtung fast immer besser als die andere. Meine Vermutung ist, dass es besser in die
Post
Klasse passt, da die Zuordnung während der Erstellung oder Bearbeitung von Posts erstellt wird, wenn sich gleichzeitig andere Dinge an der Post ändern.Wenn Sie mehrere Tags zuordnen und dies in einem Datenbankupdate tun möchten, müssen Sie vor dem Update eine Liste aller Tags erstellen, die demselben Beitrag zugeordnet sind. Diese Liste passt viel besser in die
Post
Klasse.quelle
Persönlich würde ich diese Funktionalität keinem von beiden hinzufügen.
Für mich sind beide
Post
undTag
Datenobjekte, sollten also nicht mit Datenbankfunktionen umgehen. Sie sollten einfach existieren. Sie sollen Daten speichern und von anderen Teilen Ihrer Anwendung verwendet werden.Stattdessen hätte ich eine andere Klasse, die für Ihre Geschäftslogik und Daten zu Ihrer Webseite verantwortlich ist. Wenn Ihre Seite einen Beitrag anzuzeigen und damit die Benutzer Tags hinzuzufügen, dann würde die Klasse ein hat
Post
Objekt und enthält Funktionen hinzufügenTags
zu , dassPost
. Wenn Ihre Seite Tags anzeigen und damit die Benutzer Beiträge zu diesen Tags hinzuzufügen, wäre es ein enthaltenesTag
Objekt und Funktionalität hinzufügen müssenPosts
zu , dassTag
.Das bin aber nur ich. Wenn Sie der Meinung sind, dass Sie die Datenbankfunktionalität in Ihren Datenobjekten verwalten müssen, würde ich die Antwort von pdr empfehlen
quelle
Als ich diese Frage las, fiel mir als erstes eine Many-To-Many- Datenbankbeziehung ein. Posts können viele Tags haben ... Tags können viele Posts haben ... Es scheint mir, dass beide Klassen die Fähigkeit benötigen, diese Beziehung bis zu einem gewissen Grad zu verwalten.
Aus der Sicht des Beitrags ...
Wenn Sie einen Beitrag bearbeiten oder erstellen, wird eine sekundäre Aktivität zum Verwalten von Tag- Beziehungen.
IMO, die Schaffung eines völlig neuen TAG gehört nicht hierher.
Aus der Sicht des Tags ...
Sie können ein Tag erstellen, ohne es einem Beitrag zuweisen zu müssen. Die einzige Aktivität, die ich sehe, die die Interaktion mit einem Beitrag beinhaltet, ist eine Funktion zum Löschen von Tags. Diese Funktion sollte jedoch eine eigenständige Funktion sein.
Dies funktioniert nur, wenn eine Datenbankverknüpfungstabelle vorhanden ist, die die Beziehung Viele zu Viele auflöst
quelle