Come organizzi normalmente le regioni di una classe?


17

Mi chiedevo se esistesse uno standard per definire le regioni di una classe.

Attualmente uso

Fields
Constructor
Properties
Public Methods
Private Methods

Fieldsessere proprietà private ed Propertiesessere quelle pubbliche. Normalmente userò sottoregioni all'interno di questo se necessario, o occasionalmente aggiungerò altre regioni di seguito (come membri di interfaccia o baseClass).


1
Stai parlando di layout in generale o usando "#regioni"?
snmcdonald

1
@snmcdonald Uso i #regiontag per definire una sezione
Rachel

Non dovrebbe essere una domanda wiki della comunità? Non credo ci sia uno standard e la risposta potrebbe cambiare a seconda delle lingue.
Raveline

7
Comincio eliminando tutti gli #regions
Ed S.

3
@Ed S. +1 perché le regioni sono il diavolo. Tutto quello che ti permettono di fare è oscurare il fatto che il tuo file di codice è troppo grande e deve essere sottoposto a refactoring.
MattDavey,

Risposte:


4

Enum relativi alla classe o occasionalmente strutture / classi pure-data (sopra la definizione di classe effettiva)

--- Definizione della classe ---

Membri privati

CTOR / DTOR se la lingua ha DTOR

Proprietà pubbliche

Metodi di utilità (metodi privati ​​o protetti con ambito di piccole dimensioni)

Funzionalità di classe (può essere divisa in più aree a seconda dell'ambito della classe).


17

Sottoregioni? La tua classe ha una sola responsabilità ? (implicito in questo ... la mia risposta è "Raramente qualsiasi regione, tranne forse per raggruppare proprietà, costruttori e metodi" ... ma anche allora, non la uso così tanto)


2
Sto programmando in WPF in questo momento e un esempio di alcune sottoregioni che userei è un ViewModel che ha le sue proprietà pubbliche suddivise in proprietà, comandi, dati, ecc. Relative all'interfaccia utente. Questo rende molto più facile trovare ciò che sto cercando rapidamente
Rachel,

2
Perché non utilizzare grandi banner di commento anziché regioni? // ----------ViewModel Properties---------- In questo modo puoi ancora vedere il codice (o comprimerlo con delineare e vedere i membri). Le regioni servono a nascondere le cose. Il codice non dovrebbe essere nascosto, a meno che non sia generato automaticamente o qualcosa del genere.
Kyralessa il

1
@Rachel favor composizione.
MattDavey,

10

Volevo solo confermare che intendevi "#regioni" e non il layout di classe in generale.

Sono sorpreso che nessuno abbia menzionato per evitare l'uso delle regioni. Comprendo che il PO vuole fare un sondaggio sulla definizione delle regioni, ma vorrei sollevare un punto di vista alternativo.

Evito le regioni. Mi piace vedere il codice con cui sto lavorando. Se trovi difficile trovare quello che stai cercando, usa la piegatura del codice e raggruppa insieme costrutti di classe simili.

Perché odio le regioni? CTRL+M,Le CTRL+M,Ocommuterà la piegatura del codice. Tuttavia, quando collassa nasconde l'intera regione. Ho solo bisogno di comprimere metodi / proprietà / commenti.

Se ci sono troppe regioni forse è un odore di codice e la tua classe sta facendo troppo lavoro. Jeff Atwood fornisce un buon post sulle regioni che merita una lettura.

La mia citazione preferita su #regions:

No, non userò #regioni. E no, NON NEGOZIO CON I TERRORISTI. Sta 'zitto.

- Jeff Atwood

Detto questo, so che molti programmatori insistono per usarli. Questa domanda è soggettiva. Avevo appena pensato di offrire un'alternativa.


1
Ecco una macro per comprimere le definizioni ma espandere le regioni, nel caso in cui sei bloccato a lavorare con persone innamorate delle regioni: stackoverflow.com/questions/523220/awesome-visual-studio-macros/… Funziona bene a meno che tu non sia lavorare con persone veramente malate che mettono le regioni nei metodi .
Kyralessa il

Una macro molto utile! Non sono sicuro del perché non lo abbiano realizzato in Visual Studio, tuttavia, grazie.
Snmcdonald,

Il mio capo adora le regioni, le adora. Ama anche le lezioni private interne e metodi enormi. Il nostro codice ha una classe con circa una dozzina di regioni che la dividono, 3 classi interne e alcuni metodi così lunghi che hanno una dozzina di regioni di livello superiore al loro interno, con sotto-regioni all'interno di quelle.
CodexArcanum,

4

Varia da una lingua all'altra. Dato che sono un programmatore Delphi, tendo a seguire la convenzione standard Delphi, che assomiglia a questa:

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;

Lo trovo un buon modo per organizzare le informazioni che sono facili da leggere e comprendere.


3
Trovo abbastanza sorprendente che privato, protetto, pubblico e pubblicato siano ordinati in ordine alfabetico e incapsulatorio e tutti iniziano con P!
Peter Turner,

divertente, io no. Ho sempre scoperto che era più naturale elencare per publicprimo, poiché la maggior parte degli utenti si preoccupa solo delle publiccose.
Matthieu M.

Ho sempre trovato questa convenzione un'idea davvero sciocca. Cosa ha a che fare la visibilità con la funzionalità? In ogni caso, ho sempre usato le interfacce per definire la funzionalità pubblica, ma ho implementato l'interfaccia come protetta sulla classe. Gli unici elementi che raggrupperò costantemente sono i metodi e le proprietà pubblicati per i componenti, altrimenti raggruppo sempre per Interfacce ed ereditarietà, usando più parole chiave di visibilità secondo necessità. Quegli elementi che sono unici per l'implementazione della classe (vale a dire: non sostituisce) dovrebbero davvero essere elencati per primi.
S.Robins,

3

Tendo a disporli nel modo seguente:

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

Non ho usato un linguaggio che usi Propertiesquindi è per questo che non sono definiti. Ho messo metodi e campi privati ​​in fondo perché se qualcun altro sta usando questo file nel loro codice, dovrebbero preoccuparsi solo dell'API, che è roba pubblica. E tutti gli editor di testo che conosco, e anche gli IDE, impostano il cursore in alto quando si aprono i file.


+1 per mettere in fondo i campi privati. Raggruppo i metodi pubblici dall'interfaccia che implementano e metto quelli che non implementano alcuna interfaccia in alto, subito dopo i costruttori / distruttori.
Sjoerd

2

È una richiesta di giudizio per me. Uso le regioni quando sono necessarie per la leggibilità.

Uso anche un colore diverso nella combinazione di colori di Visual Studio (attualmente un rosso scuro) per distinguerli dal resto del codice.


Un esempio di dove potrei usare un #region: se scrivo un metodo di test per un unit test che richiede uno snippet multilinea di XML, la stringa XML interromperà il solito rientro (poiché inizia lungo il margine sinistro di la finestra del codice. Per nascondere la bruttezza, la avvolgerò in una # regione, in modo da poterla comprimere.


2

Il libro Clean Code di Bob Martin dedica l'intero quinto capitolo alla formattazione. Ci sono un paio di punti chiave che sento sintetizzare bene.

  • La maggior parte dei tentativi di raggruppare variabili e metodi in base a visibilità e pulizia non ha molto senso e ti fa navigare molto nel codice.
  • Mantenere i metodi che si chiamano l'un l'altro verticalmente vicini riduce la quantità di navigazione che devi fare e rende più facile trovare le cose.
  • Il tuo treno di pensieri non si romperà se devi fermarti e pensare "a quale regione appartiene questo bit di codice?" ogni pochi minuti.
  • Le variabili di istanza dovrebbero in genere essere poche e probabilmente utilizzate ovunque, pertanto appartengono ai vertici della classe in cui saranno più facili da individuare. All'interno di tale metodo devono esistere variabili e dichiarazioni che verranno utilizzate da un solo metodo. Se utilizzati solo da un paio di metodi, dovrebbero essere vicini verticalmente ma al di sopra dei pochi metodi che li utilizzano.

Mantenere il codice organizzato con elementi che interagiscono comunemente verticalmente vicini tra loro rimuove efficacemente qualsiasi necessità di creare aree specifiche. Se il tuo codice è così lungo che richiede che le regioni nascondano molto codice, forse è un odore di codice che indica che la classe sta provando a fare troppo. Forse alcune funzionalità possono essere spostate in una classe di utilità o trasferite a un antenato.

Se devi "nascondere" il codice perché è troppo lungo o troppo "brutto", allora probabilmente avrai problemi più grandi di cui preoccuparti se usare o meno le regioni. Personalmente non ho mai bisogno di usarli, e quando lavoro sul codice di qualcun altro, trovo che devo sempre aprirli tutti comunque, quindi perché preoccuparsi?


1
+1 - Sono sorpreso che questo non sia stato menzionato in modo più evidente. Il principio di coesione si applica anche al modo in cui si espone il codice e il raggruppamento per modificatore di accesso (il più delle volte) è controproducente.
Daniel B,

0

Al momento ho corsi di layout come questo:

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

e quindi anteporre il livello di accesso a ciascuna dichiarazione (tipo di, a volte raggruppa per accesso). Ero solito fare il raggruppamento di livello superiore per accesso, ma ad un certo punto, non so quando, non ha funzionato abbastanza bene come sopra. Ad esempio in C ++ / CLI (che al momento sono costretto a usare :-() puoi farlo, che rovina il raggruppamento per accesso:

public: property int SomeProperty
{
private: void set (int value) { ... }
public: int get () { ... }
}

Cosa sono i "membri" in fondo? Per me questo è un termine catchall per tutti i pezzi di una classe.
Mason Wheeler,

@ Mason: dovrebbero essere "variabili membro" per evitare confusione.
Skizz,

Non riesco davvero a raggruppare le cose per tipo in quel modo. Qual è la differenza tra un metodo e una proprietà davvero? Non sono mai andato alla ricerca di proprietà di una classe, cercherò comunque un codice logicamente correlato, che si tratti di proprietà, metodi o altro.
Ed S.

0

Frangia lunatica: non lo so, almeno quando si tratta di C #. Tra Visual Studio e R # posso magicamente navigare verso qualsiasi membro o implementazione, quindi non ha senso ossessionarsi da queste cose; inizia a digitare dove si trova il cursore.


0

Come Wyatt e un paio di altre risposte, in genere evito anche l'uso delle regioni. Le regioni hanno uno scopo; per nascondere il codice che non si desidera guardare. Se hai un sacco di codice in una classe che non vuoi guardare, e quindi hai bisogno di molte regioni per permetterti di comprimere quel codice, allora probabilmente hai troppo codice nella classe. ReSharper non rispetta le regioni quando decide dove posizionare un nuovo codice, a meno che non abbia creato la regione (cosa che fa per le implementazioni dell'interfaccia).

L'unico uso delle regioni che trovo accettabile è nascondere il codice "inevitabilmente brutto"; codice che si occupa di dettagli di implementazione specifici che non possono essere ben progettati internamente agli standard attuali. Questo è di solito un codice esoterico avanzato che generalmente non dovrebbe essere confuso dal programmatore junior medio una volta scritto. Queste sono cose come:

  • Alcune implementazioni di interfaccia integrate (IDisposable, IConvertible, a volte IEnumerable o IComparable in quanto richiedono implementazioni generiche e non generiche)
  • P / Invoke esterni incorporati e strutture correlate.
  • Finalizzatori / distruttori (di solito va con IDisposable)
  • Si aggancia alla memoria non gestita / puntatori / codice "non sicuro".
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.