Sind verschachtelte Klassen unterbewertet?


9

Ich versuche nicht zu sagen, dass ich etwas weiß, was alle anderen nicht wissen, aber ich habe immer mehr Designs mit verschachtelten Klassen gelöst, daher bin ich neugierig, ein Gefühl dafür zu bekommen, wie akzeptabel es ist, diese scheinbar selten verwendeten zu verwenden Entwurfsmechanismus.

Dies führt mich zu der Frage: gehe ich aus Gründen, die ich entdecken werde, wenn sie zurückkommen, um mich zu beißen, einen von Natur aus schlechten Weg oder sind verschachtelte Klassen vielleicht etwas, das unterschätzt wird?

Hier sind zwei Beispiele, für die ich sie gerade verwendet habe: https://gist.github.com/3975581 - das erste hat mir geholfen, eng miteinander verbundene heirarchische Dinge zusammenzuhalten, das zweite hat mir ermöglicht, Arbeitern Zugang zu geschützten Mitgliedern zu gewähren ...


Ich möchte mich nur für die Antworten / Erkenntnisse bedanken - ich bin mir nicht sicher, wie ich eine Antwort auswählen soll, also werde ich sie verlassen, während ich über den Rat
nachdenke,

Antworten:


6

Ich würde dies nicht als "selten verwendeten Entwurfsmechanismus" bezeichnen - zumindest nicht allgemein: Obwohl es Geschäfte gibt, in denen einige Mitwirkende die Verwendung verschachtelter Klassen missbilligen, ist dies überhaupt keine obskure Funktion.

Obwohl die Existenz von Klassen mit Assembly-Sichtbarkeit und die Einführung von Lambdas den Bedarf an verschachtelten Klassen * erheblich verringert hat , bleiben sie eine gültige Entwurfswahl. Obwohl es einige Überschneidungen mit internen Klassen in einem Namespace gibt, ist die Funktion für verschachtelte Klassen einzigartig, da Sie eine Klasse vollständig in einer anderen Klasse ausblenden können.


* Die Verwendung einer ähnlichen Funktion in Java ist viel höher, da andere in C # verfügbare Alternativen in Java nicht vorhanden sind.


Ist es also gut, eine Klasse gemäß dem Wesen des OOP-Designs vollständig in einer anderen Klasse zu verstecken?
Maxood

1
@Maxood Es ist gut, eine Klasse auszublenden, wenn Sie sie ausblenden können. Der Benutzer Ihrer API sollte so wenig wie möglich über die Implementierung Ihrer API wissen.
dasblinkenlight

3

Denken Sie für einen Moment daran, dass Sie eine Klasse in einer anderen Klasse schreiben, die an keiner anderen Stelle in Ihrem Programm verwendet wird. Denn wenn Sie es woanders verwenden würden, würden Sie es zu einer gewöhnlichen öffentlichen Klasse machen, genau wie alle anderen.

Das, was OOP großartig machen soll (Wiederverwendbarkeit), fehlt hier also. Was könnten Sie außerdem mit einer verschachtelten Klasse erreichen, die Sie mit gewöhnlichen Methoden und privaten Mitgliedern innerhalb der Elternklasse nicht erreichen könnten?

Ein nützliches Softwaremuster mit verschachtelten Klassen finden Sie hier .


10
Ich habe das Wiederverwendbarkeits-Ding nie gekauft, zumindest nicht so, wie es normalerweise ausgedrückt wird. (1) Das Aufrufen von vorhandenem Code / vorhandenen Klassen (über die Sie anscheinend sprechen und die ich normalerweise als Definition der Wiederverwendung sehe) hat absolut nichts mit OOP zu tun, sondern ist lediglich eine grundlegende Modularität. (2) Der Subtyp-Polymorphismus, der ein definierendes Merkmal von OOP ist, ermöglicht die Wiederverwendung von Client-Code, indem die spezifische Implementierung irrelevant gemacht wird , dh er funktioniert genauso, unabhängig davon, ob auf die konkrete Klasse zugegriffen werden kann oder nicht. IOW ist die Wiederverwendung, die ich kaufe, aber es funktioniert genauso gut mit verschachtelten Klassen.

1
Ich würde sagen, es gibt auch die von der übergeordneten Klasse angegebene Namespace-Isolierung. Wenn Sie also möchten, könnten beide Klassen A und B die verschachtelte Klasse "Params" und den Zugriff auf nicht öffentliche Mitglieder der enthaltenden Klasse haben. Sind das nicht beide Gründe, innere Klassen zu haben, die außerhalb der Klasse verwendet werden?
Aaron Anodide

@AaronAnodide Das sollte eine Antwort auf eine gute Möglichkeit sein, verschachtelte Klassen zu verwenden. Es ist genau wie / warum ich sie benutze, es hilft, den Code zu organisieren.
Izkata

2

am I going down an inherintly bad path

Ich denke, in Ihrem zweiten Beispiel (den Arbeiter-Unterklassen) sind Sie es definitiv. Sie haben jede Unterklasse einem bestimmten Status in der Superklasse zugeordnet. Jedes Mal, wenn Sie der Superklasse einen Status hinzufügen möchten, müssen Sie an drei Stellen eine Änderung vornehmen (Status zur Superklasse hinzufügen, eine neue Unterklasse hinzufügen und den Konstruktor der abgeleiteten Klasse ändern, um die Unterklasse zur Liste hinzuzufügen ).

Die Verwendung verschachtelter Klassen für den Zugriff auf private Mitglieder scheint eine gültige Verwendung zu sein (ich habe es nie persönlich getan), aber Ihr spezieller Fall funktioniert hier nicht.

Wie für das Körperteil Beispiel. Da alle verschachtelten Klassen öffentlich sind, tun Sie nur Namespace. Wenn diese Klassen mehr Funktionen enthalten, stellen Sie möglicherweise fest, dass die verschachtelten Klassen nur die Schnittstellen überladen und Sie den Code durchsuchen, um etwas Bestimmtes zu finden. Ich stelle auch fest, dass Sie aufgrund verschachtelter Klassen gezwungen sind, Namenskonventionen zu brechen und Ihre Klassen in Kleinbuchstaben zu benennen (möglicherweise war dies eine Wahl). Aber diese Argumente sind oberflächlicher als alles, was tatsächlich falsch ist.

Es sei denn, Sie mussten natürlich einen körperlosen Arm implementieren. Dann ist es verwirrend, einen Arm zu erstellen, indem man Folgendes tut, weil es keinen Körper / Rumpf / Seite gibt. (Beachten Sie auch das verwirrende Gehäuse).

arm newArm = new Body.torso.side.arm("");

1

Der einzige Vorteil, den ich mir verschachtelte Klassen vorstellen kann, ist, dass sie privat (oder geschützt) gemacht werden können. Ich würde sagen, in diesem Fall können verschachtelte Klassen Ihnen helfen , die Funktionalität zu kapseln , wenn eine Klasse von der äußeren Klasse und nur von dieser Klasse verwendet werden soll.


1

Nach meiner Erfahrung verschachtelte Klassen

  • Kam zurück, um mich zu verfolgen
  • Wurde verwendet, als ich Ecken schneiden wollte
  • Das Testen zu einem Albtraum gemacht
  • Hatte negative Auswirkungen auf die Trennung von Bedenken und das Gesamtdesign

Habe einen kurzen Blick auf deine Klasse geworfen und sofort denke ich, dass:

  • Es ist schmerzhaft, es anzusehen, weil die Klasse riesig ist
  • Ich kann "Finger" nicht testen, ohne so ziemlich den ganzen Körper zu erschaffen
  • Ich kann nicht mehrere Implementierungen von Torso haben. Scheint in einem "menschlichen Körper" -Kontext nicht so offensichtlich, aber in einem anderen Szenario würde dies offensichtlich werden.

Warum trennen Sie Ihre Klasse nicht in mehrere Klassen und geben ihnen separate Namespaces? Z.B

WindowsGame1.PhysicalModel.UpperBody
WindowsGame1.PhysicalModel.LowerBody
WindowsGame1.PhysicalModel.UpperBody.Arms
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.