Wie ordnen Sie normalerweise die Regionen einer Klasse an?

17

Ich habe mich gefragt, ob es einen Standard für die Anordnung der Regionen einer Klasse gibt.

Ich benutze derzeit

Fields
Constructor
Properties
Public Methods
Private Methods

Fieldsals Privateigentum und Propertiesals öffentliches Eigentum. Normalerweise verwende ich Subregionen innerhalb dieser, falls erforderlich, oder füge gelegentlich andere Regionen darunter hinzu (z. B. Interface- oder BaseClass-Mitglieder).

Rachel
quelle
1
Sprechen Sie über das Layout im Allgemeinen oder verwenden Sie "#regions"?
snmcdonald
1
@snmcdonald Ich benutze #regionTags, um einen Abschnitt zu definieren
Rachel
Sollte dies nicht eine Community-Wiki-Frage sein? Ich glaube nicht, dass es einen Standard gibt, und die Antwort kann sich je nach Sprache ändern.
Raveline
7
Ich beginne mit dem Löschen aller #regions
Ed S.
3
@Ed S. +1, weil Regionen der Teufel sind. Alles, was Sie damit tun können, ist die Tatsache zu verschleiern, dass Ihre Codedatei zu groß ist und überarbeitet werden muss.
MattDavey

Antworten:

4

Klassenbezogene Aufzählungen oder gelegentlich Strukturen / reine Datenklassen (oberhalb der tatsächlichen Klassendefinition)

--- Klassendefinition ---

Private Mitglieder

CTORs / DTORs, wenn die Sprache DTORs hat

Öffentliche Objekte

Dienstprogrammmethoden (private oder geschützte Methoden mit kleinem Umfang)

Klassenfunktionalität (Kann je nach Umfang der Klasse in mehrere Regionen unterteilt werden).

Pax Noctis
quelle
17

Unterregionen? Hat Ihre Klasse eine Einzelverantwortung ? (implizit ... meine Antwort lautet "Selten irgendwelche Regionen, außer vielleicht um Eigenschaften, Konstruktoren und Methoden zu gruppieren" ... aber selbst dann benutze ich es nicht so oft.)

MIA
quelle
2
Ich programmiere gerade in WPF und ein Beispiel für einige Subregionen, die ich verwenden würde, ist ein ViewModel, dessen öffentliche Eigenschaften in UI-bezogene Eigenschaften, Befehle, Daten usw. aufgeteilt sind. Dadurch ist es viel einfacher zu finden, was ich bin auf der Suche nach schnell
Rachel
2
Warum nicht große Kommentarbanner anstelle von Regionen verwenden? // ----------ViewModel Properties---------- Auf diese Weise können Sie den Code immer noch sehen (oder ihn mit Gliederung reduzieren und die Mitglieder sehen). Regionen dienen dazu, Dinge zu verstecken . Code sollte nicht ausgeblendet werden, es sei denn, er wurde automatisch generiert oder so.
Kyralessa
1
@ Rachel gefallen Zusammensetzung.
MattDavey
10

Ich wollte nur bestätigen, dass Sie "#regions" und nicht das Klassenlayout im Allgemeinen meinten.

Ich bin überrascht, dass niemand erwähnt hat, um die Verwendung von Regionen zu vermeiden. Ich verstehe, dass das OP eine Umfrage zum Layout von Regionen durchführen möchte, aber ich möchte einen alternativen Standpunkt ansprechen.

Ich vermeide Regionen. Ich sehe gerne den Code, mit dem ich arbeite. Wenn Sie Schwierigkeiten haben, das Gesuchte zu finden, verwenden Sie Code Folding und gruppieren Sie ähnliche Klassenkonstrukte.

Warum hasse ich Regionen? CTRL+M,Lund CTRL+M,Oschaltet die Codefaltung um. Beim Zusammenklappen wird jedoch die gesamte Region ausgeblendet. Ich muss nur Methoden / Eigenschaften / Kommentare reduzieren.

Wenn es zu viele Regionen gibt, riecht es vielleicht nach Code und Ihre Klasse leistet zu viel Arbeit. Jeff Atwood bietet einen guten Beitrag zu Regionen, die es wert sind, gelesen zu werden.

Mein Lieblingszitat zu #regions:

Nein, ich werde keine #regions verwenden. Und nein, ich verhandele nicht mit Terroristen. Halte den Mund, halt den Rand, Halt die Klappe.

- Jeff Atwood

Trotzdem weiß ich, dass viele Programmierer darauf bestehen, sie zu verwenden. Diese Frage ist subjektiv. Ich hatte nur gedacht, ich würde eine Alternative anbieten.

snmcdonald
quelle
1
Hier ist ein Makro zum Einsturz zu Definitionen aber Regionen zu erweitern, falls Sie sich stecken die Arbeit mit Menschen aus Regionen verliebt: stackoverflow.com/questions/523220/awesome-visual-studio-macros/... Es funktioniert gut , es sei denn , du bist Arbeit mit wirklich kranken Menschen, die Regionen in Methoden stecken .
Kyralessa
Ein sehr nützliches Makro! Ich bin mir nicht sicher, warum sie es nicht in Visual Studio eingebaut haben, trotzdem, danke.
Snmcdonald
Mein Chef liebt Regionen, liebt sie. Er liebt auch private innere Klassen und große Methoden. In unserem Code gibt es eine Klasse mit etwa einem Dutzend Regionen, drei inneren Klassen und einigen Methoden, die so lang sind, dass sie ein Dutzend Regionen der obersten Ebene enthalten, in denen sich Unterregionen befinden.
CodexArcanum
4

Es variiert von Sprache zu Sprache. Da ich ein Delphi-Codierer bin, folge ich normalerweise der Delphi-Standardkonvention, die so aussieht:

type
  TMyClass = class(TBaseClass)
  private
    private fields
    private methods
  protected
    protected fields
    protected methods
    protected properties
  public
    constructor(s)
    destructor
    public methods
    public properties
  end;

Ich finde es eine gute Möglichkeit, Informationen zu organisieren, die einfach zu lesen und zu verstehen sind.

Mason Wheeler
quelle
3
Ich finde es ziemlich erstaunlich, dass privat, geschützt, öffentlich und veröffentlicht sowohl alphabetisch als auch kapselförmig geordnet sind und alle mit P beginnen!
Peter Turner
amüsant, tue ich nicht. Ich habe immer festgestellt, dass es natürlicher ist, publiczuerst aufzulisten , da sich die meisten Benutzer nur um publicDinge kümmern .
Matthieu M.
Ich habe diese Konvention immer als eine wirklich dumme Idee empfunden. Was hat Sichtbarkeit mit Funktionalität zu tun? Auf jeden Fall habe ich immer Interfaces verwendet, um die öffentliche Funktionalität zu definieren, aber das Interface als geschützt für die Klasse implementiert. Die einzigen Elemente, die ich konsistent gruppieren werde, sind Published-Methoden und -Eigenschaften für Komponenten. Ansonsten gruppiere ich immer nach Schnittstellen und Vererbung und verwende bei Bedarf mehrere Sichtbarkeitsschlüsselwörter. Die Elemente, die für die Klassenimplementierung eindeutig sind (dh keine Überschreibungen), sollten wirklich zuerst aufgeführt werden.
S.Robins
3

Ich neige dazu, sie folgendermaßen zu gestalten:

Public fields (usually static constants)
Constructors
Public methods
Private methods
Private fields

Habe keine Sprache benutzt Properties, die benutzt wird , deshalb sind diese nicht angelegt. Ich setze private Methoden und Felder ganz unten, denn wenn jemand anderes diese Datei in seinem Code verwendet, sollte er sich nur mit der API befassen müssen, die das öffentliche Zeug ist. Alle mir bekannten Texteditoren und sogar IDEs setzen den Cursor beim Öffnen von Dateien ganz oben.

gablin
quelle
+1 für das Setzen von privaten Feldern unten. Ich gruppiere öffentliche Methoden nach der von ihnen implementierten Schnittstelle und setze diejenigen, die keine Schnittstelle implementieren, nach den Konstruktoren / Destruktoren.
Sjoerd
2

Es ist ein Urteilsspruch für mich. Ich benutze Regionen, wenn sie für die Lesbarkeit benötigt werden.

Ich verwende auch eine andere Farbe in meinem Visual Studio-Farbschema (derzeit ein Dunkelrot), um sie vom Rest des Codes abzuheben.


Ein Beispiel für die Verwendung einer #region: Wenn ich eine Testmethode für einen Komponententest schreibe, für den ein mehrzeiliges XML-Snippet erforderlich ist, unterbricht der XML-String den üblichen Einzug (da er am linken Rand von beginnt) Um die Hässlichkeit zu verbergen, werde ich es in eine #Region verpacken, damit ich es zusammenklappen kann.

Robert Harvey
quelle
2

Bob Martins Clean Code- Buch widmet sich im gesamten 5. Kapitel der Formatierung. Es gibt ein paar wichtige Punkte, die meiner Meinung nach gut zusammengefasst sind.

  • Die meisten Versuche, Variablen und Methoden nach Sichtbarkeit und Sauberkeit zu gruppieren, ergeben wenig Sinn und führen dazu, dass Sie häufig im Code navigieren.
  • Indem Sie Methoden, die sich vertikal aufrufen, eng zusammenhalten, reduzieren Sie den Navigationsaufwand und erleichtern das Auffinden von Objekten.
  • Ihr Gedankengang wird nicht unterbrochen, wenn Sie anhalten und sich überlegen müssen, in welche Region dieser Code gehört. alle paar Minuten.
  • Instanzvariablen sollten normalerweise wenige sein und wahrscheinlich überall verwendet werden, daher gehören sie an die Spitze der Klasse, wo sie am einfachsten zu finden sind. Variablen und Deklarationen, die nur von einer Methode verwendet werden, müssen in dieser Methode vorhanden sein. Wenn sie nur von wenigen Methoden verwendet werden, sollten sie vertikal nahe beieinander liegen, jedoch über den wenigen Methoden, die sie verwenden.

Indem Sie Ihren Code mit häufig wechselwirkenden Elementen vertikal dicht nebeneinander anordnen, müssen Sie keine bestimmten Bereiche erstellen. Wenn Ihr Code so lang ist, dass Regionen viel Code verbergen müssen, ist dies möglicherweise ein Codegeruch, der darauf hinweist, dass die Klasse versucht, zu viel zu tun. Möglicherweise kann ein Teil der Funktionalität in eine Utility-Klasse verschoben oder an einen Vorfahren übertragen werden.

Wenn Sie den Code "verstecken" müssen, weil er zu lang oder zu "hässlich" ist, haben Sie wahrscheinlich größere Probleme, als sich Gedanken darüber zu machen, ob Sie Regionen verwenden sollen oder nicht. Persönlich muss ich sie nie verwenden, und wenn ich an dem Code eines anderen arbeite, muss ich sie sowieso immer alle öffnen. Warum also die Mühe machen?

S.Robins
quelle
1
+1 - Ich bin überrascht, dass dies nicht weiter oben erwähnt wurde. Das Kohäsionsprinzip gilt auch für das Layout Ihres Codes, und das Gruppieren nach Zugriffsmodifikatoren ist (meistens) kontraproduktiv.
Daniel B
0

Ich habe derzeit Layout-Klassen wie folgt:

class types
constructors
destructor
accessors
methods
properties (where properties are present in the language)
member variables

und dann die Zugriffsebene jeder Deklaration voranstellen (Art, manchmal nach Zugriff gruppieren). Früher habe ich Gruppierungen nach Zugriff auf oberster Ebene durchgeführt, aber irgendwann weiß ich nicht, wann, es hat nicht ganz so gut funktioniert wie oben. Zum Beispiel in C ++ / CLI (wozu ich momentan gezwungen bin :-() können Sie dies tun, was die Gruppierung nach Zugriff durcheinander bringt:

public: property int SomeProperty
{
private: void set (int value) { ... }
public: int get () { ... }
}
Skizz
quelle
Was sind "Mitglieder" am unteren Rand? Für mich ist das ein Sammelbegriff für alle Teile einer Klasse.
Mason Wheeler
@Mason: sollte "Mitgliedsvariablen" sein, um Verwirrung zu vermeiden.
Skizz
Ich bekomme es wirklich nicht hin, Dinge nach Typ zu gruppieren. Was ist der Unterschied zwischen einer Methode und einer Eigenschaft? Ich habe noch nie nach den Eigenschaften einer Klasse gesucht. Ich werde jedoch nach logisch verwandtem Code suchen, ob es sich um Eigenschaften, Methoden oder was auch immer handelt.
Ed S.
0

Wahnsinnige Randantwort: Das tue ich nicht, zumindest wenn es um C # geht. Zwischen Visual Studio und R # kann ich auf magische Weise zu jedem Mitglied oder jeder Implementierung navigieren, sodass es keinen Grund gibt, über dieses Zeug nachzudenken. fang einfach an zu tippen, wo der Cursor ist.

Wyatt Barnett
quelle
0

Wie Wyatt und einige andere Antworten vermeide ich auch generell die Verwendung von Regionen. Regionen haben einen Zweck; um Code zu verstecken, muss man sich nicht umsehen. Wenn Sie in einer Klasse viel Code haben, den Sie sich nicht ansehen müssen, und Sie daher viele Regionen benötigen, um den Code zu reduzieren, dann haben Sie wahrscheinlich zu viel Code in der Klasse. ReSharper berücksichtigt Regionen nicht, wenn entschieden wird, wo neuer Code abgelegt werden soll, es sei denn, es hat die Region erstellt (was bei Schnittstellenimplementierungen der Fall ist).

Die einzige Verwendung von Regionen, die ich für akzeptabel halte, besteht darin, "unvermeidlich hässlichen" Code zu verbergen. Code, der sich mit spezifischen Implementierungsdetails befasst, die nach den aktuellen Standards intern nicht gut strukturiert werden können. Dies ist in der Regel fortgeschrittener, esoterischer Code, mit dem ein durchschnittlicher Junior-Programmierer nach dem Schreiben im Allgemeinen nichts anfangen sollte. Dies sind Dinge wie:

  • Bestimmte integrierte Schnittstellenimplementierungen (IDisposable, IConvertible, manchmal IEnumerable oder IComparable, da sie generische und nicht generische Implementierungen erfordern)
  • Eingebettete P / Invoke-Externe und verwandte Strukturen.
  • Finalizer / Destruktoren (normalerweise mit IDisposable)
  • Hooks zu nicht verwaltetem Speicher / Zeigern / "unsicherem" Code.
KeithS
quelle