Ist es unkonventionell, eine Unterklasse innerhalb ihrer Elternklasse zu definieren?

8

Ist es üblich, eine Unterklasse wie folgt in der Elternklasse zu definieren?

%Vor%

Oder ist es sinnvoller, ein Modul zu erstellen, das die Unterklassen enthält?

%Vor%

Oder um eine "Basis" -Klasse in einem Modul zu erstellen und die Unterklassen innerhalb desselben Moduls zu definieren?

%Vor%

Oder ist es besser, eine Namenskonvention zu erzwingen?

%Vor%

Es scheint, dass jede Bibliothek eine andere Namensraum- / Namenskonvention wählt.

Welches ist das beste zu verwenden?
Was sind die Vor- und Nachteile von jedem?

    
RyanScottLewis 19.02.2013, 21:27
quelle

3 Antworten

9

TL; DR : Der üblichste und beste Weg, dies zu tun, ist mit einem Modul, das eine Basisklasse und ihre Unterklassen enthält. Aber lass uns über alles gehen.

Es gibt nicht viele offizielle Quellen dazu; Es ist jedoch der Stil, Module zu verwenden, um Bibliotheken, Code und Klassengruppen zu enthalten.

Unterklassen in der Oberklasse

Vorteile :

  • In sich abgeschlossen: Das gesamte Klassensystem ist unter einem Namen enthalten

Nachteile:

  • Unnatürlich: Wer würde denken, in eine Superklasse für eine Unterklasse zu schauen?

Die Unterklassen in einer Oberklasse zu haben hängt wirklich von der Situation ab. Alle Vorteile dieser Methode werden jedoch auch durch die Modulmethode erreicht. In der Praxis wird dies jedoch nicht getan. Klassen sind hier, um Methoden, Instanzvariablen, Klassenmethoden usw. zu enthalten. Aber Klassen können als letzte Ebene der Verschachtelung betrachtet werden - Sie haben keine Klasse in einer Klasse, es sei denn, es handelt sich um einen sehr spezifischen Umstand.

Der eine Fall, in dem ich dies sinnvoll finden kann, ist ein Fall, in dem Unterklassen nur durch die Oberklasse verwendet werden, zum Beispiel eine Klasse Formatter , die interne Unterklassen wie XML , PDF usw. hat Angenommen, Sie verwenden diese Klassen nur, indem Sie beispielsweise Formatter.new(:xml) ausführen. Aber wenn wir das tun, sollten die Unterklassen privat und für die Außenwelt sowieso nicht zugänglich sein. Und zu diesem Zeitpunkt ist die Vererbung sehr C ++ y-mäßig und überhaupt nicht Ruby.

Basisklasse außerhalb des Moduls, Unterklassen innerhalb

Vorteile:

  • Ich kann mir keine vorstellen

Nachteile:

  • Implicates Non-conected: Wenn Element nicht im selben Namensraum wie seine Kinder ist, was, abgesehen von dem Namen, sagt mir, dass es sogar verwandt ist?

Diese Methode ist sehr unnatürlich. Es sieht so aus, als ob Element nichts mit seinen Kindern zu tun hat, oder wenn es anders betrachtet wird, dass Kinder interne Implementierungsdetails sind, die nicht behandelt werden sollen. So oder so sieht es aus wie schäbige, nachlässige Namensgebung und schlechte Code-Struktur-Planung. Wenn ich Code mit diesem Code lesen würde, müsste ich mir den Inhalt des Elements Moduls anschauen, um zu sehen, dass Element überhaupt unterklassiert wurde - und das ist nicht die natürlichste Sache.

Klasse und Unterklassen im Modul (beste Lösung)

Vorteile:

  • Enthalten: Die Oberklasse und alle Element-Klassen sind in einem Namensraum enthalten, so dass sie leicht importiert, benötigt, iteriert usw. werden können. Unterstützt auch die Metaprogrammierung.
  • Includable: Die Klassen können leicht in jeden Code eingefügt werden.
  • Clear: Es gibt eine offensichtliche Assoziation zwischen include und den Unterklassen. Sie sind offensichtlich ein Bündel von Funktionen.

Nachteile:

  • Ermutigt die langsame Benennung: Dies ermutigt Sie, Klassen wie Element zu nennen, die sehr mehrdeutig sind.

Dies ist der beste Ansatz. Es macht die Klassen zu einem ordentlichen Bündel, während es immer noch eine offensichtliche Assoziation und ein offensichtliches "Hier, benutze meine Base -Klasse" (im Gegensatz zu der Unterklassen-in-Klassen-Strategie) zeigt. Dies ist auch sehr hilfreich für das Metaprogrammieren, bei dem alles in einem Modul entscheidend ist, damit die Dinge funktionieren. Schließlich funktioniert das gut mit Konstrukten wie Div , autoload , require_relative usw. Diese zeigen, dass die Sprache so entworfen wurde, um verwendet zu werden.

Erzwinge eine Namenskonvention

Vorteile:

  • Einfach: Keine Komplexität hier.
  • Entfernt Mehrdeutigkeiten: Entfernt Mehrdeutigkeiten von kurzen Namen wie include oder Div , indem sie in Para und DivElement .
  • umgewandelt werden

Nachteile:

  • Archaisch: Namenskonventionen zum Gruppieren von Klassen oder Methoden sollten nur in Sprachen existieren, die keine bessere Möglichkeit haben, dies zu tun, wie C oder Objective-C. C ++ löschte es, sobald es Namespaces bekam.
  • Keine programmatische Gruppierung: Diese Namenskonventionen machen die Klassenstruktur, obwohl sie für Menschen klar sind, für Metaprogrammierungscodes sehr trübe und machen es dem Programm unmöglich, die Klassen als Gruppe zu behandeln
  • Verschmutzter globaler Namespace: Dies erzeugt viele, viele Namen im globalen Namespace, was immer eine schlechte Idee ist.

Dies ist eine sehr , SEHR schlechte Lösung. Es kodiert für schlampigen C-Code mit wenig Organisation und wenig Sinn. Diese Arten von Namenskonventionen sollten nur in Sprachen verwendet werden, in denen es keine bessere Lösung gibt, und Ruby hat viele bessere Lösungen. Selbst das Definieren aller Klassen in einem Array ist besser als eine Namenskonvention.

Hinweis: Wenn Sie das wirklich möchten, können Sie eine Namenskonvention für kurze Namen wie ParaElement oder Div definieren, solange Sie sie in einem Modul behalten, so dass Para lautet. Dies verstößt jedoch gegen DRY, und ich würde es nicht vorschlagen.

Fazit

Sie haben also wirklich zwei Möglichkeiten.Stellen Sie einfach alles in ein Modul:

%Vor%

Oder fügen Sie alles in ein Modul mit einer Namenskonvention ein:

%Vor%

Ich sptere ersteres für die Klarheit, die Verwendung von Standardmethoden und Metaprogrammierungsgründen.

    
Linuxios 23.02.2013, 16:12
quelle
3

Dies ist ein Problem, mit dem ich viele Male konfrontiert war - Sie haben einige gemeinsame Funktionen und ein paar verschiedene Implementierungsklassen, die es verwenden - die gemeinsame Funktionalität und der Namensraum für die Implementierungsklassen haben denselben Namen.

>

Ich hatte nie ein Problem, eine Unterklasse wie in Ihrem ersten Beispiel unter der Elternklasse zu definieren - außer , weil es manchmal andere Entwickler in meinem Team verwirrt hat. Je nachdem, mit wem Sie arbeiten und was ihre Präferenzen sind, glaube ich nicht, dass es ein Problem mit diesem Ansatz gibt.

Ich würde immer noch den zweiten Ansatz mit einem anderen Namen für den Namensraum bevorzugen, wenn es einen Namen gibt, der Sinn ergibt. Wenn nicht, würde ich den ersten Ansatz verwenden.

Ich würde es vermeiden, Namen wie Base zu verwenden, da diese Art von generischem Namen meiner Meinung nach dazu anregt, nur altes Zeug hineinzuwerfen, während ein Name, der beschreibt, was die Klasse macht, Sie (hoffentlich) zum Nachdenken anregt Mal fügst du eine Methode hinzu, wenn sie wirklich dorthin gehört.

Und ich bin wirklich kein Fan von zusammengesetzten Namen wie in Ihrem Namenskonvention Beispiel, das ich mir mit einer Art von vage Gefühl, dass es wie Datenbank-Normalisierung ist rechtfertigen - jedes Feld (oder Klassenname) sollte nur ein Stück enthalten von Informationen.

Jedenfalls hoffe ich, dass dir das weiterhilft. Ich kann nicht wirklich aus anderen Quellen als meiner eigenen Erfahrung schöpfen (es ist für dich, zu entscheiden, ob du glaubst, dass das "glaubwürdig" ist), da ich glaube, dass es keine absolute Antwort auf diese Frage gibt. Es ist zu einem großen Teil subjektiv.

    
Russell 23.02.2013 15:00
quelle
1

Namensraum und Vererbung dienen verschiedenen Zwecken. Verwenden Sie den Namensraum, um ein Modul in einem anderen zu kapseln. Verwenden Sie Vererbung, um ein Modul zu definieren, das die Methoden / Variablen / Konstanten eines anderen standardmäßig verwendet.

Es könnte im Prinzip passieren, dass Sie möchten, dass ein Modul innerhalb des Namensraums von demselben Modul ist und von demselben Modul erbt, aber das hängt von Ihrem Anwendungsfall ab. Ohne über einen bestimmten Anwendungsfall zu diskutieren, kann nicht entschieden werden, welcher der von Ihnen vorgeschlagenen Wege der beste ist.

    
sawa 19.02.2013 21:55
quelle

Tags und Links