Best practice: ordinamento di pubblico / protetto / privato all'interno della definizione di classe?


92

Sto iniziando un nuovo progetto da zero e voglio che sia pulito / abbia buoni standard di codifica. In che ordine gli sviluppatori esperti qui amano disporre le cose all'interno di una classe?

A: 1) metodi pubblici 2) metodi privati ​​3) vars pubblici 4) vars privati

B: 1) vars pubbliche 2) vars private 3) metodi pubblici 4) metodi privati

C: 1) vars pubblici 2) metodi pubblici 3) metodi privati ​​4) vars privati

In genere mi piace mettere le variabili statiche pubbliche all'inizio, ma poi un metodo statico pubblico dovrebbe essere elencato prima del tuo costruttore, o il costruttore dovrebbe essere sempre elencato per primo? Questo genere di cose...

So che è finto ma mi chiedevo: quali sono le migliori pratiche per questo?

PS: no non uso Cc #. Lo so. Sono un luddite.


9
Non c'è niente di sbagliato nel non usare C #. Non ho mai scritto un punto di C # in tutti i miei anni come sviluppatore professionista. Usa il linguaggio appropriato per il compito e dì a chiunque dica qualcosa di diverso dove può farlo!
Ether

Risposte:


142

In Clean Code , Robert C.Martin consiglia ai programmatori di mettere sempre le variabili membro all'inizio della classe (prima le costanti, poi i membri privati) e i metodi dovrebbero essere ordinati in modo tale che leggano come una storia che non causa il lettore deve saltare troppo il codice. Questo è un modo più sensato per organizzare il codice piuttosto che tramite un modificatore di accesso.


10
Ho avuto fortuna anche aggiungendo: getters / setters last. Aiuta le classi a sentirsi meno ingombranti, per me.
Dean J,

5
Costruttori in alto, subito dopo le variabili membro. In OOP, l'esecuzione inizia con l'istanza dell'oggetto.
Asaf

6
Indurre il lettore a saltare troppo sul codice probabilmente deve essere bilanciato con il costringere il lettore a leggere tutti i dettagli essenziali dei metodi privati. La metafora del giornale è probabilmente fraintesa in quanto i tuoi metodi pubblici dovrebbero rappresentare ampiamente ciò che fa la tua classe e i tuoi metodi privati ​​forniscono i dettagli (quasi come una nota a piè di pagina a cui puoi fare riferimento se necessario).
Kenny Hung,

1
Non ho capito bene. Hai detto: (prima le costanti, poi i membri privati) . OK. Dove vanno allora i membri del pubblico?
Honey

1
@ Miele Andrebbero subito dopo le costanti e i membri privati. Quindi sarebbe nel seguente ordine: costanti, membri privati, membri pubblici.
Pierre Gillet,

48

La migliore pratica è essere coerenti .

Personalmente, preferisco mettere publicprima i protectedmetodi, poi i metodi, poi i privatemetodi. I dati dei membri dovrebbero in generale essere sempre privati ​​o protetti, a meno che tu non abbia una buona ragione per non farlo.

La mia logica per mettere i publicmetodi all'inizio è che definisce l' interfaccia per la tua classe, quindi chiunque legga il tuo file di intestazione dovrebbe essere in grado di vedere immediatamente queste informazioni.

In generale, privatee protectedsoci sono meno importanti per la maggior parte delle persone in cerca di file di intestazione, a meno che non stanno prendendo in considerazione la modifica dei meccanismi interni della classe. Tenerli "fuori mano" garantisce che queste informazioni vengano conservate solo in base alla necessità di sapere , uno degli aspetti più importanti dell'incapsulamento.


LeopardSkikPBH, sono totalmente d'accordo ... ha senso! Immagino di essere stato confuso sul fatto che all'interno di questo, var o funcs abbiano la precedenza. Grazie!
tempname

11
Non sono d'accordo che la migliore pratica sia essere coerenti. Esistono molti modi per scrivere costantemente codice illeggibile e non stampabile.
jason

3
@ Jason è come dire che non è la migliore pratica stare dalla tua parte della strada perché puoi ancora avere incidenti lì.
Rex M

1
@ Jason - Forse avrei dovuto essere più chiaro. In questo caso particolare, abbastanza soggettivo (ordinamento dei metodi), penso che la migliore pratica sia essere coerenti. Tutti avranno opinioni sul modo migliore per ordinare le cose, ma se sei coerente per natura dovrebbe essere abbastanza sostenibile. Sono d'accordo che "essere coerenti" non è sempre la migliore pratica per tutte le aree del codice, specialmente se si considera la scarsa qualità del codice con cui spesso si ha a che fare.
LeopardSkinPillBoxHat

4
@ Rex M: No, quello che ho detto non è affatto simile alla tua interpretazione. Il punto è che il semplice essere coerenti non è un argomento forte in questo caso. Per alcuni casi la coerenza va bene (ad esempio, il posizionamento delle parentesi graffe). Ma le scelte qui influenzano effettivamente la leggibilità del codice. Pertanto, è necessario un argomento più forte della coerenza.
jason

8

Penso di avere una filosofia diversa su questo rispetto alla maggior parte. Preferisco raggruppare insieme elementi correlati. Non sopporto di dover saltare per lavorare con una classe. Il codice dovrebbe fluire e l'utilizzo di un ordinamento piuttosto artificiale basato sull'accessibilità (pubblico, privato, protetto, ecc.) O istanza contro statico o membro contro proprietà contro funzione non aiuta a mantenere un buon flusso. Quindi, se navighi un metodo pubblico Methodche è implementato da metodi helper privati HelperMethodA, HelperMethodBecc. Allora piuttosto che avere questi metodi distanti l'uno dall'altro nel file, li terrò vicini l'uno all'altro. Allo stesso modo, se ho un metodo di istanza implementato da un metodo statico, raggrupperò anche questi.

Quindi le mie lezioni spesso assomigliano a questo:

class MyClass {
    public string Method(int a) {
        return HelperMethodA(a) + HelperMethodB(this.SomeStringMember);
    }

    string HelperMethodA(int a) { // returns some string }

    string HelperMethodB(string s) { // returns some string }

    public bool Equals(MyClass other) { return MyClass.Equals(this, other); }

    public static bool Equals(MyClass left, MyClass right) { // return some bool }

    public double SomeCalculation(double x, double y) {
        if(x < 0) throw new ArgumentOutOfRangeException("x");
        return DoSomeCalculation(x, y); 
    }

    const double aConstant;
    const double anotherConstant;
    double DoSomeCalculation(double x, double y) {
        return Math.Pow(aConstant, x) * Math.Sin(y) 
            + this.SomeDoubleMember * anotherConstant;
    }       
}

8

Personalmente mi piace avere il pubblico al top, protetto e poi privato. La ragione di ciò è che quando qualcuno apre l'intestazione vede prima a cosa può accedere, poi più dettagli mentre scorre verso il basso.

Non si dovrebbero guardare i dettagli di implementazione di una classe per usarla, quindi il design della classe non è fatto bene.


3

Mi importava molto. Negli ultimi anni utilizzando IDE moderni praticamente tutto è solo 1 o 2 sequenze di tasti di distanza, ho lasciato che i miei standard si rilassassero sostanzialmente. Ora, comincio con le statistiche, le variabili membro, quindi i costruttori, dopodiché non mi preoccupo molto.

In C # lascio che Resharper organizzi le cose automaticamente.


Sono d'accordo. La mia modalità normale di navigazione tra i membri in un file consiste nell'usare uno strumento integrato nell'IDE o nell'editor che sto utilizzando. Il raggruppamento effettivo dei membri diventa secondario. Tuttavia, sono d'accordo che i membri debbano essere raggruppati per evitare un ordine casuale puro e io uso resharper per raggruppare e ordinare automaticamente.
Phillip Ngan

2

Questo sarebbe il mio ordine

  1. Variabili statiche
  2. Metodi statici
  3. Variabili pubbliche
  4. Variabili protette
  5. Variabili private
  6. Costruttori
  7. Metodi pubblici
  8. Metodi protetti
  9. Metodi privati

Uso le seguenti regole:

  • statico prima di tutto
  • variabili prima dei costruttori prima dei metodi (considero i costruttori nella categoria dei metodi)
  • pubblico prima protetto prima privato

L'idea è che tu definisca l'oggetto (i dati), prima dei comportamenti (metodi). Le statistiche devono essere separate perché non sono realmente parte dell'oggetto, né del suo comportamento.


grazie barkmadley ... è interessante! che metteresti 4 e 5 prima del costruttore. Ci penserò sicuramente
tempname

Come questo ordine anche se avere metodi statici vicino alla parte superiore è interessante. Ho lavorato con uno sviluppatore che ha messo le variabili private in fondo, ho potuto vedere l'idea ma non mi sembrava giusta
Carlton

2

In genere sono d'accordo con l'ordine pubblico, protetto, privato così come i dati statici, i dati dei membri, l'ordine delle funzioni dei membri.

Anche se a volte raggruppo membri simili (getter e setter) generalmente preferisco elencare i membri all'interno di un gruppo ALFABETICAMENTE in modo che possano essere individuati più facilmente.

Mi piace anche allineare i dati / funzioni verticalmente. Faccio tab / spazio a destra abbastanza in modo che tutti i nomi siano allineati nella stessa colonna.


1
Ehi, un "distanziatore di tabulazione" dopo il mio cuore! :-) Non sono ossessivo compulsivo. Onesto non lo sono!
tempname

1

A ciascuno il suo, e come dice Elzo, gli IDE moderni hanno reso più facile trovare i membri ei loro modificatori in modo semplice con icone colorate nei menu a discesa e simili.

La mia opinione è che sia più importante per il programmatore sapere per cosa è stata progettata la classe e come ci si può aspettare che si comporti.

Quindi, se è un Singleton, metto prima la semantica (classe statica getInstance ()).

Se è una fabbrica concreta, metto prima la funzione getNew () e le funzioni register / initialize.

... e così via. Quando dico prima, intendo subito dopo i c'tors e d'tor, poiché sono il modo predefinito di istanziare qualsiasi classe.

Le funzioni che seguono sono quindi in:

  1. ordine logico delle chiamate (ad es. initialize (), preProcess (), process (), postProcess ()) o
  2. funzioni correlate insieme (come funzioni di accesso, utilità, manipolatori ecc.),

a seconda che la classe fosse concepita principalmente per essere un archivio dati con alcune funzioni o un fornitore di funzioni con pochi membri di dati.


0

Alcuni editor, come Eclipse e la sua discendenza, consentono di riordinare nella vista struttura le variabili e i metodi, in ordine alfabetico o come a pagina.


0

La sequenza di public seguita da protected e private è più leggibile per me, è meglio descrivere la logica di classe nei commenti in cima al file di intestazione semplicemente e gli ordini di chiamata di funzione per capire quale dose di classe e algoritmi utilizzati all'interno.

Sto usando Qt c ++ da un po 'e vedo un nuovo tipo di parole chiave come signale slotpreferisco continuare a ordinare come sopra e condividere la mia idea con voi qui.

#ifndef TEMPLATE_H
#define TEMPLATE_H


class ClassName
{
    Q_OBJECT
    Q_PROPERTY(qreal startValue READ startValue WRITE setStartValue)
    Q_ENUMS(MyEnum)

public:

    enum MyEnum {
        Hello = 0x0,
        World = 0x1
    };

    // constructors

    explicit ClassName(QObject *parent = Q_NULLPTR);
    ~ClassName();

    // getter and setters of member variables

    // public functions (normal & virtual) -> orderby logic

public slots:

signals:

protected:

    // protected functions it's rule followed like public functions


private slots:

private:

    // methods

    // members

};

#endif // TEMPLATE_H
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.