Welche Idee steckt hinter der Benennung von Klassen mit dem Suffix "Info", z. B. "SomeClass" und "SomeClassInfo"?

20

Ich arbeite in einem Projekt, das sich mit physischen Geräten befasst, und ich war verwirrt, wie ich einige Klassen in diesem Projekt richtig benennen soll.

Angesichts der Tatsache, dass die tatsächlichen Geräte (Sensoren und Empfänger) eine Sache sind und ihre Darstellung in der Software eine andere, denke ich darüber nach, einige Klassen mit dem Suffix-Namensmuster "Info" zu benennen.

Während beispielsweise a Sensoreine Klasse ist, die den tatsächlichen Sensor darstellt (wenn er tatsächlich mit einem Arbeitsgerät verbunden ist), wird SensorInfosie verwendet, um nur die Eigenschaften eines solchen Sensors darzustellen. Zum Beispiel würde ich beim Speichern von Dateien a SensorInfoin den Datei-Header serialisieren, anstatt a zu serialisieren Sensor, was nicht einmal Sinn macht.

Aber jetzt bin ich verwirrt, weil es einen Mittelweg im Lebenszyklus von Objekten gibt, auf dem ich nicht entscheiden kann, ob ich die eine oder andere verwenden oder wie ich eine von einer anderen erhalten soll oder ob beide Varianten tatsächlich nur zu einer Klasse zusammengefasst werden sollen.

Außerdem ist die allzu verbreitete Beispielklasse Employeeoffensichtlich nur eine Darstellung der realen Person, aber meines Wissens würde niemand vorschlagen, die Klasse EmployeeInfostattdessen zu benennen .

Die Sprache, mit der ich arbeite, ist .NET, und dieses Benennungsmuster scheint im gesamten Framework verbreitet zu sein, zum Beispiel mit den folgenden Klassen:

  • Directoryund DirectoryInfoKlassen;
  • Fileund FileInfoKlassen;
  • ConnectionInfoKlasse (ohne Korrespondenzklasse Connection);
  • DeviceInfoKlasse (ohne Korrespondenzklasse Device);

Meine Frage lautet also: Gibt es eine allgemeine Begründung für die Verwendung dieses Benennungsmusters? Gibt es Fälle, in denen es sinnvoll ist, Namenspaare ( Thingund ThingInfo) zu haben, und andere Fälle, in denen nur die ThingInfoKlasse oder die ThingKlasse ohne ihr Gegenstück existieren sollte?

Heltonbiker
quelle
5
Ben Aaronson hat es in seiner Antwort unten richtig gemacht; Das InfoSuffix unterscheidet eine staticKlasse mit Dienstprogrammmethoden von ihrem zustandsbehafteten Gegenstück. Es ist keine "Best Practice" als solche; Es ist nur ein Weg, den das .NET-Team gefunden hat, um ein bestimmtes Problem zu lösen. Sie hätten genauso gut kommen mit FileUtilityund Fileaber File.DoSomething()und FileInfo.FileNamescheinen besser zu lesen.
Robert Harvey
1
Es ist erwähnenswert, dass dies ein allgemeines Muster ist, jedoch mit so vielen unterschiedlichen Namenskonventionen, wie es Sprachen und APIs gibt. Wenn Sie beispielsweise in Java über eine stateful-Klasse Fooverfügen, verfügen Sie möglicherweise über eine nicht instanziierbare Utility-Klasse Foos. Bei der Benennung kommt es auf die Konsistenz innerhalb der API und idealerweise über alle APIs auf der Plattform hinweg an.
Kevin Krumwiede
1
"Ja wirklich?" "Niemand würde vorschlagen, die Klasse EmployeeInfo zu benennen" ?? NIEMAND? Das scheint für etwas nicht so offensichtliches ein wenig stark zu sein.
ThePopMachine
@ThePopMachine Ich stimme zu, dass das Wort "nobody" in diesem Fall möglicherweise zu schwer ist, aber EmployeeBeispiele finden sich in Dutzenden, entweder online oder in klassischen Büchern, die ich noch nicht gesehen EmployeeInfohabe (vielleicht, weil ein Mitarbeiter ein Lebewesen ist, nicht ein technisches Konstrukt wie eine Verbindung oder eine Datei). Aber einverstanden, wenn die Klasse EmployeeInfoin einem Projekt vorgeschlagen würde, könnte sie meiner Meinung nach ihren Nutzen haben.
Heltonbiker

Antworten:

21

Ich denke, "info" ist eine falsche Bezeichnung. Objekte haben Status und Aktionen: "info" ist nur ein anderer Name für "state", der bereits in OOP eingebunden ist.

Was versuchst du hier wirklich zu modellieren? Sie benötigen ein Objekt, das die Hardware in der Software darstellt, damit es von anderem Code verwendet werden kann.

Das ist leicht zu sagen, aber wie Sie herausgefunden haben, steckt noch mehr dahinter. "Darstellung von Hardware" ist überraschend breit. Ein Objekt, das dies tut, hat mehrere Bedenken:

  • Gerätekommunikation auf niedriger Ebene, unabhängig davon, ob es sich um eine USB-Schnittstelle, eine serielle Schnittstelle, TCP / IP oder eine proprietäre Verbindung handelt.
  • Verwaltender Staat. Ist das Gerät eingeschaltet? Bereit, mit Software zu sprechen? Beschäftigt?
  • Ereignisse verarbeiten. Das Gerät hat Daten erzeugt: Jetzt müssen Ereignisse generiert werden, die an andere interessierte Klassen weitergegeben werden.

Bestimmte Geräte wie Sensoren haben weniger Probleme als beispielsweise ein Drucker / Scanner / Fax-Multifunktionsgerät. Ein Sensor erzeugt wahrscheinlich nur einen Bitstrom, während ein komplexes Gerät komplexe Protokolle und Interaktionen aufweisen kann.

Wie auch immer, zurück zu Ihrer spezifischen Frage, es gibt verschiedene Möglichkeiten, dies abhängig von Ihren spezifischen Anforderungen sowie der Komplexität der Hardware-Interaktion zu tun.

Hier ist ein Beispiel, wie ich die Klassenhierarchie für einen Temperatursensor entwerfen würde:

  • ITemperatureSource: Schnittstelle, die alles darstellt, was Temperaturdaten erzeugen kann: ein Sensor, kann sogar ein File-Wrapper oder fest codierte Daten sein (man denke an Scheintests).

  • Acme4680Sensor: Sensor ACME Modell 4680 (ideal zum Erkennen, wenn der Roadrunner in der Nähe ist). Dies kann mehrere Schnittstellen implementieren: Vielleicht erkennt dieser Sensor sowohl Temperatur als auch Luftfeuchtigkeit. Dieses Objekt enthält einen Status auf Programmebene, z. B. "Ist der Sensor angeschlossen?". und "was war die letzte Lesung?"

  • Acme4680SensorComm: Wird ausschließlich zur Kommunikation mit dem physischen Gerät verwendet. Es behält nicht viel Zustand bei. Es wird zum Senden und Empfangen von Nachrichten verwendet. Es gibt eine C # -Methode für jede Nachricht, die die Hardware versteht.

  • HardwareManager: Dient zum Abrufen von Geräten. Dies ist im Wesentlichen eine Factory, die Instanzen zwischenspeichert: Für jedes Hardwaregerät sollte nur eine Instanz eines Geräteobjekts vorhanden sein. Es muss klug genug sein zu wissen, dass, wenn Thread A den ACME-Temperatursensor und Thread B den ACME-Feuchtigkeitssensor anfordert, diese tatsächlich dasselbe Objekt sind und an beide Threads zurückgegeben werden sollten.


Auf der obersten Ebene haben Sie Schnittstellen für jeden Hardwaretyp. Sie beschreiben Aktionen, die Ihr C # -Code auf den Geräten ausführen würde, und verwenden dabei C # -Datentypen (nicht z. B. Byte-Arrays, die der Raw-Gerätetreiber möglicherweise verwendet).

Auf derselben Ebene haben Sie eine Aufzählungsklasse mit einer Instanz für jeden Hardwaretyp. Der Temperatursensor kann ein Typ sein, der Feuchtigkeitssensor ein anderer.

Eine Ebene darunter befinden sich die tatsächlichen Klassen, die diese Schnittstellen implementieren: Sie stellen ein Gerät dar, das dem oben beschriebenen Acme4680Sensor I ähnelt. Jede bestimmte Klasse kann mehrere Schnittstellen implementieren, wenn das Gerät mehrere Funktionen ausführen kann.

Jede Geräteklasse verfügt über eine eigene private Kommunikationsklasse, die die einfache Aufgabe der Kommunikation mit der Hardware übernimmt.

Außerhalb des Hardwaremoduls ist nur die Ebene interfaces / enum sowie der HardwareManager sichtbar. Die HardwareManager-Klasse ist die Factory-Abstraktion, die die Instanziierung von Geräteklassen, das Zwischenspeichern von Instanzen (Sie möchten wirklich nicht, dass zwei Geräteklassen mit demselben Hardwaregerät kommunizieren) usw. verwaltet. Eine Klasse, die einen bestimmten Sensortyp benötigt, fordert den HardwareManager auf, diesen abzurufen das Gerät für die bestimmte Aufzählung, das dann ermittelt, ob es bereits instanziiert ist, ob es nicht erstellt und initialisiert werden soll usw.

Ziel ist es, die Geschäftslogik von der Hardware-Logik auf niedriger Ebene zu entkoppeln . Wenn Sie Code schreiben, der Sensordaten auf den Bildschirm druckt, sollte es diesen Code nicht interessieren, welchen Sensortyp Sie genau dann haben, wenn diese Entkopplung vorhanden ist, die sich auf diese Hardwareschnittstellen konzentriert.


Beispiel für ein UML-Klassendiagramm mit dem in dieser Antwort beschriebenen Entwurf

Hinweis: Es gibt Verknüpfungen zwischen dem HardwareManager und jeder Geräteklasse, die ich nicht gezeichnet habe, da das Diagramm zu einer Pfeilsuppe geworden wäre.


quelle
Sehr interessante Antwort. Ich würde Sie um eine schnelle Bearbeitung bitten: Lassen Sie uns genauer wissen, was die Vererbung / Eindämmung / Zusammenarbeit zwischen den vier Klassen ist, die Sie erwähnt haben. Vielen Dank!
Heltonbiker
Ich habe ein UML-Klassendiagramm hinzugefügt. Hilft das?
2
Ich würde sagen, das ist eine umwerfende Antwort, und es wird mir nicht nur sehr helfen, sondern ich glaube, dass es in Zukunft noch viel mehr Menschen helfen kann. Außerdem bildet das von Ihnen bereitgestellte Klassenhierarchie-Beispiel unsere Problem- und Lösungsdomänen bemerkenswert gut ab. Danke dir nochmal!
Heltonbiker
Als ich die Frage las, stellte ich fest, dass mehr los war, also ging ich ein bisschen über den Haufen und teilte das gesamte Design. Dies ist mehr als ein einfaches Benennungsproblem, da die Namen auf das Design hinweisen. Ich habe mit Systemen gearbeitet, die auf diese Weise gebaut wurden, und sie haben ziemlich gut funktioniert.
11

Es kann ein wenig schwierig sein, hier eine einzige vereinheitlichende Konvention zu finden, da diese Klassen über eine Reihe von Namespaces verteilt sind ( ConnectionInfoscheint in CrystalDecisionsund DeviceInfoin zu sein System.Reporting.WebForms).

Wenn man sich diese Beispiele ansieht, scheint es jedoch zwei unterschiedliche Verwendungen des Suffixes zu geben:

  • Unterscheiden einer Klasse, die statische Methoden bereitstellt, in eine Klasse, die Instanzmethoden bereitstellt. Dies ist der Fall für die System.IOKlassen, wie durch ihre Beschreibungen unterstrichen:

    Verzeichnis :

    Macht statische Methoden zum Erstellen, Verschieben und Auflisten von Verzeichnissen und Unterverzeichnissen verfügbar. Diese Klasse kann nicht vererbt werden.

    DirectoryInfo :

    Macht Instanzmethoden zum Erstellen, Verschieben und Auflisten von Verzeichnissen und Unterverzeichnissen verfügbar. Diese Klasse kann nicht vererbt werden.

    InfoDies scheint eine etwas seltsame Wahl zu sein, macht jedoch den Unterschied relativ deutlich: Eine DirectoryKlasse könnte vernünftigerweise entweder ein bestimmtes Verzeichnis darstellen oder allgemeine verzeichnisbezogene Hilfsmethoden bereitstellen, ohne einen Status zu haben, während DirectoryInfodies nur die erstere sein könnte.

  • Hervorheben, dass die Klasse nur Informationen enthält und kein Verhalten liefert , das von dem Namen ohne Suffix vernünftigerweise erwartet werden kann .

    Ich denke , dass der letzte Teil dieses Satzes könnte das Stück des Puzzles sein , dass unterscheidet, sagen, ConnectionInfoaus EmployeeInfo. Wenn ich eine Klasse mit dem Namen hätte Connection, würde ich davon ausgehen, dass sie mir tatsächlich die Funktionalität bietet, die eine Verbindung bietet - ich würde nach Methoden wie void Open()usw. suchen . Allerdings würde niemand, der bei Verstand ist, damit rechnen, dass eine EmployeeKlasse dies tatsächlich könnte Mach was ein Real Employeemacht, oder suche nach Methoden wie void DoPaperwork()oder bool TryDiscreetlyBrowseFacebook().

Ben Aaronson
quelle
1
Ich danke Ihnen sehr für Ihre Antwort! Ich glaube, der erste Punkt in Ihrer Antwort beschreibt definitiv, was in .NET-Klassen vor sich geht, aber der zweite Punkt hat mehr Wert (und ist im Übrigen anders), weil er die beabsichtigte Abstraktion besser aufdeckt: eine Sache, die man gegen eine verwenden sollte was zu beschreiben ist. Es war schwer zu entscheiden, welche Antwort zu akzeptieren war.
Heltonbiker
4

Im Allgemeinen Infokapselt ein Objekt Informationen über den Status eines Objekts zu einem bestimmten Zeitpunkt . Wenn ich das System auffordere, eine Datei anzusehen und mir ein FileInfoObjekt mit der Größe zuzuordnen, würde ich erwarten, dass dieses Objekt die Größe der Datei zum Zeitpunkt der Anforderung angibt (oder genauer gesagt die Größe von die Datei irgendwann zwischen dem Zeitpunkt des Anrufs und der Rückkehr). Wenn sich die Größe der Datei zwischen der Rückkehr der Anforderung und der FileInfoUntersuchung des Objekts ändert , würde ich nicht erwarten, dass sich eine solche Änderung im FileInfoObjekt niederschlägt.

Beachten Sie, dass sich dieses Verhalten stark von dem eines FileObjekts unterscheidet. Wenn eine Anforderung zum Öffnen einer Festplattendatei im nicht exklusiven Modus ein FileObjekt mit einer SizeEigenschaft ergibt , würde ich erwarten, dass sich der zurückgegebene Wert ändert, wenn sich die Größe der Festplattendatei ändert, da das FileObjekt nicht nur den Status von darstellt eine Datei - es repräsentiert die Datei selbst .

In vielen Fällen müssen Objekte, die an eine Ressource gebunden sind, bereinigt werden, wenn ihre Dienste nicht mehr benötigt werden. Da *InfoObjekte nicht an Ressourcen gebunden sind, müssen sie nicht bereinigt werden. Infolgedessen ist es in Fällen, in denen ein InfoObjekt die Anforderungen eines Kunden erfüllt, möglicherweise besser, einen Code zu verwenden, als ein Objekt zu verwenden, das die zugrunde liegende Ressource darstellt, dessen Verbindung zu dieser Ressource jedoch bereinigt werden müsste.

Superkatze
quelle
1
Dies ist nicht gerade falsch, aber es scheint nicht von .NET Namensmuster sehr gut auf alle zu erklären, da die FileKlasse nicht instanziiert werden kann und FileInfoObjekte tun Updates mit dem zugrunde liegenden Dateisystem.
Nathan Tuggy
@ NathanTuggy Ich bin damit einverstanden, dass dies nicht gut mit dieser Namenskonvention in .NET zusammenhängt, aber in Bezug auf mein aktuelles Problem halte ich es für sehr relevant und könnte eine konsistente Lösung herbeiführen. Ich habe diese Antwort positiv bewertet, aber es ist schwierig, nur eine zu wählen, die akzeptiert wird ...
heltonbiker
@ NathanTuggy: Ich würde nicht empfehlen, .NET als Modell für eine Art von Konsistenz zu verwenden. Es ist ein gutes und nützliches Framework, das viele gute Ideen zusammenfasst, aber auch ein paar schlechte Ideen in den Mix einfließen lassen.
Supercat
@supercat: Sicher; Es scheint nur seltsam, eine Frage zu beantworten: "Warum macht .NET Dinge auf diese Weise?" mit "Es wäre eine gute Idee, die Dinge% THIS_WAY% zu tun".
Nathan Tuggy
@ NathanTuggy: Ich habe mich nicht an die genauen Angaben der fraglichen Klassen erinnert, aber ich dachte, ich hätte FileInfonur statisch erfasste Informationen. Nicht wahr Außerdem hatte ich noch nie Gelegenheit, Dateien im nicht exklusiven Modus zu öffnen, aber es sollte möglich sein, und ich würde erwarten, dass es eine Methode gibt, die die aktuelle Größe einer Datei angibt, auch wenn das zum Öffnen verwendete Objekt nicht vorhanden ist genannt File( in der Regel nur verwende ich ReadAllBytes, WriteAllBytes, ReadAllText, WriteAllText, etc.).
Supercat
2

Angesichts der Tatsache, dass die tatsächlichen Geräte (Sensoren und Empfänger) eine Sache sind und ihre Darstellung in der Software eine andere, denke ich darüber nach, einige Klassen mit dem Suffix-Namensmuster "Info" zu benennen.

Während beispielsweise a Sensoreine Klasse ist, die den tatsächlichen Sensor darstellt (wenn er tatsächlich mit einem Arbeitsgerät verbunden ist), wird SensorInfosie verwendet, um nur die Eigenschaften eines solchen Sensors darzustellen. Zum Beispiel würde ich beim Speichern von Dateien a SensorInfoin den Datei-Header serialisieren, anstatt a zu serialisieren Sensor, was nicht einmal Sinn macht.

Ich mag diese Unterscheidung nicht. Alle Objekte sind "Darstellungen in Software". Das ist, was das Wort "Objekt" bedeutet.

Nun ist es möglicherweise sinnvoll, Informationen zu einem Peripheriegerät vom eigentlichen Code zu trennen, der mit dem Peripheriegerät verbunden ist. So verfügt beispielsweise ein Sensor über eine SensorInfo, die die meisten Instanzvariablen sowie einige Methoden enthält, für die keine Hardware erforderlich ist, während die Sensorklasse für die tatsächliche Interaktion mit dem physischen Sensor verantwortlich ist. Sie haben keine, es Sensorsei denn, Ihr Computer hat einen Sensor, aber Sie könnten plausibel eine haben SensorInfo.

Das Problem ist, dass diese Art von Design auf (fast) jede Klasse verallgemeinert werden kann. Also musst du vorsichtig sein. Sie würden offensichtlich keine SensorInfoInfoKlasse haben, zum Beispiel. Und wenn Sie eine SensorVariable haben, verletzen Sie möglicherweise das Gesetz von Demeter, indem Sie mit ihrem SensorInfoMitglied interagieren . Nichts davon ist natürlich fatal, aber API-Design ist nicht nur für Bibliotheksautoren. Wenn Sie Ihre eigene API sauber und einfach halten, kann der Code besser verwaltet werden.

Dateisystemressourcen wie Verzeichnisse sind meiner Meinung nach sehr nahe an diesem Rand. Es gibt Situationen, in denen Sie ein Verzeichnis beschreiben möchten, auf das lokal nicht zugegriffen werden kann, aber der durchschnittliche Entwickler befindet sich wahrscheinlich nicht in einer dieser Situationen. Es ist meiner Meinung nach wenig hilfreich, die Klassenstruktur auf diese Weise zu komplizieren. Der Ansatz von Contrast Python in pathlib: Es gibt eine einzige Klasse, die "mit größter Wahrscheinlichkeit das ist, was Sie brauchen", und verschiedene Hilfsklassen, die die meisten Entwickler ignorieren können. Wenn Sie sie jedoch wirklich brauchen, bieten sie im Wesentlichen die gleiche Oberfläche, nur ohne konkrete Methoden.

Kevin
quelle
Vielen Dank für Ihre Antwort und ein dickes Lob für Ihr "have-a" -Konstrukt;) Ihre Antwort erinnert mich an die Unannehmlichkeiten, die durch das "DTO" -Konzept (Data Transfer Object) - oder dessen Geschwister, das Parameter Object - verursacht werden, das verpönt ist von orthodoxeren OO-Zeloten, weil es normalerweise keine Methoden enthält (immerhin ist es ein Datenübertragungsobjekt ). In diesem Sinne und zusammenfassend auch, was andere gesagt haben, denke ich, dass SensorInfodies eine Art DTO und / oder auch eine "Momentaufnahme" oder sogar eine "Spezifikation" wäre, die nur den Daten- / Zustandsteil des tatsächlichen SensorObjekts darstellt das "könnte nicht einmal da sein".
Heltonbiker
Wie bei den meisten Designproblemen gibt es keine feste Regel. In dem von mir bereitgestellten pathlib-Beispiel verhält es sich PureWindowsPathein bisschen wie ein Info-Objekt, verfügt jedoch über Methoden, um Dinge zu erledigen, die kein Windows-System erfordern (z. B. ein Unterverzeichnis zu entfernen, eine Dateierweiterung abzuspalten usw.). Dies ist hilfreicher als nur eine verherrlichte Struktur bereitzustellen.
Kevin
1
Nochmals ein großes Lob für den Teil "verherrlichte Struktur" :). Das erinnert mich an ein verwandtes Zitat aus Onkel Bobs Buch "Clean Code", Kapitel 6: "Erfahrene Programmierer wissen, dass die Idee, dass alles ein Objekt ist, ein Mythos ist. Manchmal möchten Sie wirklich einfache Datenstrukturen mit darauf ablaufenden Prozeduren."
Heltonbiker
2

Ich würde sagen, dass Kontext / Domäne von Bedeutung sind, da wir über hochrangigen Geschäftslogikcode und niedrigrangige Modelle, Architekturkomponenten usw. verfügen.

"Info", "Daten", "Manager", "Objekt", "Klasse", "Modell", "Controller" usw. können stinkende Suffixe sein, insbesondere auf einer niedrigeren Ebene, da jedes Objekt über einige Informationen oder Daten verfügt Diese Informationen sind nicht erforderlich.

Klassennamen der Geschäftsdomäne sollten so lauten, als ob alle Stakeholder darüber sprechen, egal ob sie komisch klingen oder nicht zu 100% die richtige Sprache sind.

Gute Suffixe für Datenstrukturen sind zB 'List', 'Map' und für Andeutungsmuster 'Decorator', 'Adapter', wenn Sie dies für notwendig halten.

Zu deinem Sensorszenario würde ich aber nicht erwarten SensorInfozu retten was dein Sensor ist SensorSpec. Infoimho ist eher eine abgeleitete Information, wie FileInfoetwa die Größe, die Sie nicht speichern oder der Dateipfad, der aus dem Pfad und dem Dateinamen aufgebaut ist, usw.

Ein weiterer Punkt:

In der Informatik gibt es nur zwei schwierige Dinge: die Ungültigmachung des Cache und das Benennen von Dingen.

- Phil Karlton

Das erinnert mich immer daran, nur ein paar Sekunden über einen Namen nachzudenken, und wenn ich keinen gefunden habe, benutze ich seltsame Namen und markiere sie mit 'TODO'-Zeichen. Ich kann es später jederzeit ändern, da meine IDE Refactoring-Unterstützung bietet. Es ist kein Firmenslogan, der gut sein muss, sondern nur ein Code, den wir jedes Mal ändern können, wenn wir wollen. Behalt das im Kopf.

Aitch
quelle
1

ThingInfo kann als hervorragender schreibgeschützter Proxy für die Sache dienen.

Siehe http://www.dofactory.com/net/proxy-design-pattern

Proxy: "Geben Sie einen Ersatz oder Platzhalter für ein anderes Objekt an, um den Zugriff darauf zu steuern."

Normalerweise hat ThingInfo öffentliche Eigenschaften ohne Setter. Diese Klassen und die Methoden für die Klasse sind sicher zu verwenden und übernehmen keine Änderungen an den Sicherungsdaten, dem Objekt oder anderen Objekten. Es treten keine Zustandsänderungen oder andere Nebenwirkungen auf. Diese können für Berichts- und Webdienste oder überall dort verwendet werden, wo Sie Informationen zum Objekt benötigen, aber den Zugriff auf das eigentliche Objekt beschränken möchten.

Verwenden Sie die ThingInfo, wann immer dies möglich ist, und beschränken Sie die Verwendung der tatsächlichen Thing auf die Zeiten, zu denen Sie das Thing-Objekt tatsächlich ändern müssen. Es beschleunigt das Lesen und Debuggen erheblich, wenn Sie sich an die Verwendung dieses Musters gewöhnen.

Shmoken
quelle
Ausgezeichnet. Ich habe heute früher meine architektonischen Bedürfnisse analysiert, in Bezug auf die Klassen, die ich in der Frage verwendet habe, und bin zu genau diesem Schluss gekommen. In meinem Fall habe ich einen, Receiverder Datenströme von vielen Sensors empfängt . Die Idee ist: Der Empfänger sollte die tatsächlichen Sensoren abstrahieren. Aber das Problem ist: Ich brauche den Sensor info , so dass ich sie bis zu einem gewissen Dateiheader schreiben kann. Die Lösung: Jeder IReceiverhat eine Liste von SensorInfo. Wenn ich Befehle an den Empfänger sende, die eine Änderung des Sensorzustands implizieren, werden diese Änderungen (über den Getter) auf dem jeweiligen Sensor wiedergegeben SensorInfo.
Heltonbiker
(Fortsetzung ...) Das heißt: Ich spreche nicht mit den Sensoren selbst, sondern nur mit dem Empfänger über übergeordnete Befehle, und der Empfänger wiederum spricht mit jedem der Sensoren. Schließlich benötige ich jedoch Informationen von den Sensoren, die ich von der Receiver-Instanz über deren List<SensorInfo>readonly-Eigenschaft erhalte.
Heltonbiker
1

Bisher scheint niemand in dieser Frage den wahren Grund für diese Namenskonvention aufgegriffen zu haben.

A DirectoryInfoist nicht das Verzeichnis. Es ist ein DTO mit Daten über das Verzeichnis. Es kann viele solcher Instanzen geben, die dasselbe Verzeichnis beschreiben. Es ist keine Einheit. Es ist ein Wegwerfwertobjekt. A DirectoryInforepräsentiert nicht das aktuelle Verzeichnis. Sie können es sich auch als Handle oder Controller für ein Verzeichnis vorstellen.

Vergleichen Sie dies mit einer Klasse namens Employee. Dies kann ein ORM-Entitätsobjekt sein und es ist das einzige Objekt, das diesen Mitarbeiter beschreibt. Wenn es ein Wertobjekt ohne Identität war, sollte es aufgerufen werden EmployeeInfo. Ein Employeesteht in der Tat für den tatsächlichen Mitarbeiter. Eine aufgerufene wertmäßige DTO-Klasse EmployeeInfowürde den Mitarbeiter eindeutig nicht darstellen, sondern ihn beschreiben oder Daten darüber speichern.

In der BCL gibt es tatsächlich ein Beispiel, in dem beide Klassen vorhanden sind: A ServiceControllerist eine Klasse, die einen Windows-Dienst beschreibt. Für jeden Dienst kann es eine beliebige Anzahl solcher Controller geben. Eine ServiceBase(oder eine abgeleitete) Klasse ist der eigentliche Dienst und es ist konzeptionell nicht sinnvoll, mehrere Instanzen davon pro Dienst zu haben.

usr
quelle
Das klingt ähnlich wie das Proxyvon @Shmoken erwähnte Muster, nicht wahr?
Heltonbiker
@heltonbiker es muss nicht unbedingt ein Proxy sein. Es könnte sich um ein Objekt handeln, das in keiner Weise mit dem, was es beschreibt, verbunden ist. Beispielsweise könnten Sie eine EmployeeInfovon einem Webdienst erhalten. Das ist kein Proxy. Ein weiteres Beispiel: Ein AddressInfonicht einmal haben , eine Sache kann es Proxy , weil eine Adresse keine Einheit ist. Es ist ein eigenständiger Wert.
USR
1
Ich verstehe, das macht Sinn!
Heltonbiker