Die Verwendung des Prinzips der "einfachen Verantwortung" zwingt meine Container dazu, öffentliche Setter zu haben

8

Ich bemühe mich sehr, die SOLID-Prinzipien zu entwerfen. Was ich gefunden habe, ist, dass wenn man das "Single Responsibility Prinzip" (das S von SOLID) benutzt, man normalerweise Klassen zwischen den Datencontainern und den Datenprozessoren aufteilen muss. Wenn ich zum Beispiel eine Klassenperson mit 5 Eigenschaften habe, die aus DB gelesen wird, anstatt alles in eine Klasse zu schreiben, erzeuge ich eine Person-Klasse mit den Eigenschaften und eine andere PersonReader-Klasse, die diese Information aus der Datenbank liest und die Person erstellt >

Wenn ich das tue, muss ich die Personeneigenschaften öffnen, damit PersonReader auf sie zugreifen kann, aber dann habe ich weniger Einkapselung, als alles in eine schwarze Box zu setzen und die Eigenschaften nur lesbar zu machen.

Fehle ich etwas oder ist das ein Nachteil dieses Prinzips?

Vielen Dank im Voraus

BEARBEITEN: Ich habe den Personenschreiber zu einem Personenleser geändert, da es nicht notwendig war, die Eigenschaften-Setter am Anfang öffentlich zu machen.

    
Ignacio Soler Garcia 10.12.2010, 18:30
quelle

4 Antworten

3

Die meisten Datenzugriffsstrategien (ORM-Techniken) beinhalten Kompromisse der von Ihnen beschriebenen Art. Die am wenigsten aufdringlichen verwenden Reflektion (oder Introspektion usw.), um Ihre Entitäten bei Bedarf zu füllen (wenn beispielsweise keine öffentlichen Setter vorhanden sind).

Nachdem Sie das gesagt haben, wenn Ihre Entitäten nur Datencontainer sind (wie im anämischen Domain-Modell ), die einzige Verantwortung Das Prinzip sollte Sie nicht wirklich interessieren, da Ihre Objekte keine komplexe Logik haben, die durch den Datenzugriffscode verfälscht würde.

    
Jeff Sternal 10.12.2010 19:03
quelle
3

Vielleicht fehlt mir etwas, aber warum schreiben Sie keinen Konstruktor für die Klasse "Person", die alle Eigenschaften akzeptiert? Auf diese Weise kann der PersonReader eine Person erstellen, ohne dass Sie die Eigenschaften der Person öffnen.

Eine weitere Option besteht darin, den Setter der Eigenschaften der Person als intern zu markieren (und die Assembly-Interna für die Assembly des PersonReaders sichtbar zu machen, wenn sie sich in einer anderen Assembly befindet). Auf diese Weise können Sie auf die Personeneigenschaften zugreifen, aber verhindern, dass sie von Personen außerhalb der Baugruppe geändert werden.

    
ItayMaoz 11.12.2010 10:20
quelle
1

Ich stimme Ihnen definitiv zu, dass Sie manchmal auf dieses Problem stoßen. Ich habe es mit der Serialisierung erlebt, die ORM ähnlich ist. In meinem Fall musste ich den Zustand eines Objekts in eine (binäre) Datei schreiben.

In manchen Fällen kann es sinnvoll sein, eine Schnittstelle zu erstellen, über die der interne Zustand geschrieben und gelesen werden kann. So würde Ihre Personenklasse zwei Metheds bekommen, die "speichern" und "laden" (oder "schreiben" und "lesen" oder was auch immer Sie für angemessen halten). Diesen Methoden wird jeweils ein "IPropertyWriter" und "IPropertyReader" übergeben. (In meinem Fall habe ich sie InStream und OutStream genannt).

Person :: save (IPropertyWriter writer) würde dann

machen %Vor%

Sie können argumentieren, dass Sie immer noch das Prinzip der einheitlichen Verantwortlichkeit verletzen, aber ich würde argumentieren, dass niemand sonst das Innere von Person kennen sollte. (Besonders in meinem Fall der Serialisierung musste ich den internen Zustand speichern, der teilweise durch Getter nicht zugänglich ist). Der Hauptpunkt ist, dass Person nicht an einen Datenbankcode gekoppelt ist. Ihr IPropertyWriter kann alles sein. Darüber hinaus ist die Verantwortung für das "Kennenlernen eigener Eigenschaften" nicht wirklich eine neue Eigenschaft, sondern hängt ohnehin an jedem Objekt an.

Sie können auch die Frage stellen, wie wahrscheinlich es ist, dass sich die Person ändert. Wenn es sehr unwahrscheinlich ist, denke ich, dass friend -Klassen wie in C ++ ein guter Weg sind, aber wenn es sich ändern sollte, würde ich lieber die Serialisierungsmethoden direkt an der Stelle haben, an der die Eigenschaften deklariert werden Aktualisieren Sie den abhängigen Code.

    
Philipp 11.12.2010 08:45
quelle
0
___ answer4415940 ___

Ich stimme Ihnen definitiv zu, dass Sie manchmal auf dieses Problem stoßen. Ich habe es mit der Serialisierung erlebt, die ORM ähnlich ist. In meinem Fall musste ich den Zustand eines Objekts in eine (binäre) Datei schreiben.

In manchen Fällen kann es sinnvoll sein, eine Schnittstelle zu erstellen, über die der interne Zustand geschrieben und gelesen werden kann. So würde Ihre Personenklasse zwei Metheds bekommen, die "speichern" und "laden" (oder "schreiben" und "lesen" oder was auch immer Sie für angemessen halten). Diesen Methoden wird jeweils ein "IPropertyWriter" und "IPropertyReader" übergeben. (In meinem Fall habe ich sie InStream und OutStream genannt).

Person :: save (IPropertyWriter writer) würde dann

machen %Vor%

Sie können argumentieren, dass Sie immer noch das Prinzip der einheitlichen Verantwortlichkeit verletzen, aber ich würde argumentieren, dass niemand sonst das Innere von Person kennen sollte. (Besonders in meinem Fall der Serialisierung musste ich den internen Zustand speichern, der teilweise durch Getter nicht zugänglich ist). Der Hauptpunkt ist, dass Person nicht an einen Datenbankcode gekoppelt ist. Ihr IPropertyWriter kann alles sein. Darüber hinaus ist die Verantwortung für das "Kennenlernen eigener Eigenschaften" nicht wirklich eine neue Eigenschaft, sondern hängt ohnehin an jedem Objekt an.

Sie können auch die Frage stellen, wie wahrscheinlich es ist, dass sich die Person ändert. Wenn es sehr unwahrscheinlich ist, denke ich, dass %code% -Klassen wie in C ++ ein guter Weg sind, aber wenn es sich ändern sollte, würde ich lieber die Serialisierungsmethoden direkt an der Stelle haben, an der die Eigenschaften deklariert werden Aktualisieren Sie den abhängigen Code.

    
___ answer4416253 ___

Vielleicht fehlt mir etwas, aber warum schreiben Sie keinen Konstruktor für die Klasse "Person", die alle Eigenschaften akzeptiert? Auf diese Weise kann der PersonReader eine Person erstellen, ohne dass Sie die Eigenschaften der Person öffnen.

Eine weitere Option besteht darin, den Setter der Eigenschaften der Person als intern zu markieren (und die Assembly-Interna für die Assembly des PersonReaders sichtbar zu machen, wenn sie sich in einer anderen Assembly befindet). Auf diese Weise können Sie auf die Personeneigenschaften zugreifen, aber verhindern, dass sie von Personen außerhalb der Baugruppe geändert werden.

    
___ qstntxt ___

Ich bemühe mich sehr, die SOLID-Prinzipien zu entwerfen. Was ich gefunden habe, ist, dass wenn man das "Single Responsibility Prinzip" (das S von SOLID) benutzt, man normalerweise Klassen zwischen den Datencontainern und den Datenprozessoren aufteilen muss. Wenn ich zum Beispiel eine Klassenperson mit 5 Eigenschaften habe, die aus DB gelesen wird, anstatt alles in eine Klasse zu schreiben, erzeuge ich eine Person-Klasse mit den Eigenschaften und eine andere PersonReader-Klasse, die diese Information aus der Datenbank liest und die Person erstellt >

Wenn ich das tue, muss ich die Personeneigenschaften öffnen, damit PersonReader auf sie zugreifen kann, aber dann habe ich weniger Einkapselung, als alles in eine schwarze Box zu setzen und die Eigenschaften nur lesbar zu machen.

Fehle ich etwas oder ist das ein Nachteil dieses Prinzips?

Vielen Dank im Voraus

BEARBEITEN: Ich habe den Personenschreiber zu einem Personenleser geändert, da es nicht notwendig war, die Eigenschaften-Setter am Anfang öffentlich zu machen.

    
___ answer4412342 ___

Die meisten Datenzugriffsstrategien (ORM-Techniken) beinhalten Kompromisse der von Ihnen beschriebenen Art. Die am wenigsten aufdringlichen verwenden Reflektion (oder Introspektion usw.), um Ihre Entitäten bei Bedarf zu füllen (wenn beispielsweise keine öffentlichen Setter vorhanden sind).

Nachdem Sie das gesagt haben, wenn Ihre Entitäten nur Datencontainer sind (wie im anämischen Domain-Modell ), die einzige Verantwortung Das Prinzip sollte Sie nicht wirklich interessieren, da Ihre Objekte keine komplexe Logik haben, die durch den Datenzugriffscode verfälscht würde.

    
___ tag123designpatterns ___ Ein Designmuster ist eine allgemeine wiederverwendbare Lösung für ein häufig auftretendes Problem im Softwaredesign. Verwenden Sie dieses Tag für Fragen, wenn Sie Probleme mit der Implementierung von Entwurfsmustern haben. Bitte verwenden Sie dieses Tag nicht bei Fragen zum Textmustervergleich. ___ tag123design ___ Design in der Programmierung ist der Akt, bestimmte Entscheidungen darüber zu treffen, wie man ein Programm am besten strukturiert, um Ziele der Zuverlässigkeit, Wartbarkeit, Korrektheit oder Benutzerfreundlichkeit zu erreichen. ___ tag123c ___ C # (sprich "Cis") ist eine objektorientierte Programmiersprache auf hohem Niveau, die für die Erstellung einer Vielzahl von Anwendungen entwickelt wurde, die auf dem .NET Framework (oder .NET Core) ausgeführt werden. C # ist einfach, leistungsfähig, typsicher und objektorientiert. ___ qstnhdr ___ Die Verwendung des Prinzips der "einfachen Verantwortung" zwingt meine Container dazu, öffentliche Setter zu haben ___ answer4412533 ​​___

Sie denken zu granular. Eine bestimmte Klasse sollte die Datenbank lesen, aber Sie benötigen keine Klasse, deren einzige Aufgabe darin besteht, eine Person zu erstellen. Das ist einfach verschwenderisch. Ein einzelner Datenbankleser sollte in der Lage sein, jede Klasse zu erstellen, die durch die Datenbank kommt - weil das seine Aufgabe ist. Aus der Datenbank lesen.

Es gibt keine Kapselungsprobleme beim Öffnen der Eigenschaften von Person, so dass DatabaseReader auf sie zugreifen kann, da Person redundant ist, wenn keine Klasse in der Lage ist, sie zu erstellen. Es ist ein fester Bestandteil jeder Klassenverantwortlichkeit, erschaffbar und zerstörbar zu sein.

    
___ tag123solidprinciples ___ Die SOLID-Prinzipien sind die fünf Prinzipien des objektorientierten Designs, die von Robert C. Martin eingeführt oder dokumentiert wurden. ___
Puppy 10.12.2010 19:26
quelle