Organizzazione dei membri di classe in saluti al modificatore di accesso

6

Se guardiamo all'implementazione tipica di una classe, di solito vediamo i membri privati definiti all'inizio e pubblici (per lo più funzioni e accessorie) definiti verso il basso. Ora, questo è uno standard di settore concordato da molte persone?

Che ne dici di mantenere i membri privati verso la fine, in quanto gli aggiornamenti e le aggiunte vengono di solito fatti ai membri pubblici (per lo più funzioni), per correggere bug o fornire miglioramenti, quindi non dobbiamo scorrere verso il basso per arrivare a la sezione di definizione della funzione.

Capisco, i buoni IDE ci permetteranno di passare a un attributo specifico, ma considerando altri fattori, come la revisione del codice, potrebbe essere conveniente avere le definizioni pubbliche all'inizio.

Qual è lo standard più accettato per l'organizzazione dei membri della classe?

    
posta Shamim Hafiz 04.01.2012 - 08:58
fonte

6 risposte

3

so we don't have to scroll down towards the end to get to the function definition section

Se ci sono così tanti membri privati in una classe che devi scorrere in basso, potresti voler guardare il design della classe. Non penso che scoprirai che il problema più grande è se hai collocato i membri privati in cima o in fondo.

Oppure, per dirla in un altro modo, se la sequenza di definizioni nelle tue classi è davvero il problema più grande che devi risolvere allora congratulazioni, hai una grande base di codice, e dovresti solo andare avanti e sviluppare funzionalità di business, piuttosto che preoccuparti di questo tipo di dettagli (che, come fai notare te stesso, il tuo IDE si preoccupa per te).

Detto questo, se i membri privati sono semplicemente membri di supporto per proprietà pubbliche, la semplice risposta, nelle versioni successive di C #, è proprietà automatiche - ma se ne hai bisogno, probabilmente sono meglio nascosti in fondo.

Se li stai utilizzando per incapsulare servizi astratti, preferirei vederli in alto in modo che io conosca, non appena entro in questa classe, che tipo di dipendenze abbia.

    
risposta data 04.01.2012 - 09:29
fonte
4

Metto i metodi pubblici nella parte superiore della mia classe poiché i metodi pubblici sono gli unici punti di ingresso nella logica della classe incapsulata.

    
risposta data 04.01.2012 - 09:30
fonte
3

Penso che la pratica di dichiarare i privati prima e pubblici in seguito sia stata ereditata da C. Quello che di solito accade è che i pubblici si riferiscono ai privati, ma non viceversa, quindi non è possibile dichiarare il pubblico prima senza usare un sacco di riferimenti avanzati molto scomodi. Quindi, c'è una lunga tradizione nel farlo e le persone ci sono abituate.

Naturalmente, con linguaggi moderni come C # non c'è motivo per farlo di più.

Detto questo, mi sento in dovere di aggiungere che non mi capita di essere particolarmente appassionato di tradizione .

    
risposta data 04.01.2012 - 11:33
fonte
1

Nel suo libro Pulisci codice Robert C. Martin sostiene che i metodi di una classe dovrebbero essere ordinati secondo l'ordine di utilizzo nella classe. Ciò inizia con un metodo pubblico, quindi con i metodi privati utilizzati dal metodo pubblico nell'ordine in cui li utilizza. I metodi privati utilizzati in quei metodi privati seguono subito dopo il metodo che li usa. Quindi i prossimi metodi pubblici, seguiti dai metodi privati associati. In questo modo, quando si legge un metodo, gli altri metodi sono utilizzati qui sotto.

Perchè questo approccio sia efficace, tuttavia, le classi devono essere davvero piccole e avere una singola responsabilità.

    
risposta data 04.01.2012 - 14:57
fonte
1

Uso la seguente ripartizione e proverò a giustificarla dopo la descrizione.

<class>
members (as in vars)
  internal members
    internal const members
    internal static members
     internal static const members
  (repeat with public, protected, private)
properties (same as members)
  ...
ctors (internal, public, protected, private)
commands (ie void returns, or success or other returns that are not pure functions)
  (internal, etc)
event handlers
 control event handlers
 remote event handlers
 other event handlers
functions (ie queries)
 (internal, etc)

Noterai uno schema di indentazione applicato qui. Questo per indicare la presenza di ciò che chiamo il modello di commenti strutturati che viene creato per prima cosa quando il file è vuoto. Ciò che i commenti fanno è fornire un layout di indentazione adeguato (per la piegatura del codice) e slot in cui i nuovi membri sono inseriti in base agli attributi dati.

Ecco un picco in C #, anche se lo uso anche per altre lingue.

La parte superiore:

//# namespace
  // Z_DOT package UtilsCL ::UtilsWin32::UtilsCL:UtilsWin32.cs  z.6566885600116177.2009.04.27.14.18.06|package
    namespace UtilsCL{
      //#class
        // Z_DOT class UtilsWin32::UtilsWin32::UtilsCL:UtilsWin32.cs  z.3959885600116177.2009.04.27.14.18.09|static-class
           /// <summary>
           /// Win32 PInvoke
           /// </summary>
          // ReSharper disable ClassNeverInstantiated.Global
          public class UtilsWin32{
            // ReSharper restore ClassNeverInstantiated.Global
            // ReSharper restore UnusedMember.Global
            //#, members
                 // ReSharper disable UnusedMember.Local
                  /// <summary>
                  /// Does nothing
                  /// </summary>
                 private void __(){
                   // ReSharper restore UnusedMember.Local
                 }
              //#i, internal    members
                //;
                //#i*, internal static     members
                  //;
                  //#i*@, internal static const members
                    //;
                //#i@, internal const     members
                  //;
                //;

A midsection, nota il commento:

//#-. private                      properties
  //;
  //#-*. private static     properties
    //;
    //#-*@. private static const properties
      // ReSharper disable InconsistentNaming
      // ReSharper disable UnaccessedField.Local
      #pragma warning disable 169
       /// <summary>
       /// Private Static Const Properties
       /// </summary>
      [SuppressMessage("Gendarme.Rules.Performance", "AvoidUnusedPrivateFieldsRule")]
      private static object __God_private_static_const_properties;
      #pragma warning restore 169
      // ReSharper restore InconsistentNaming// ReSharper restore UnaccessedField.Local
      #region "private_static_const_properties"
      // Z_DOT ppt  def:Set ::God::mrobbinsassoc::com::OmegaApp:God.cs  z.7121082100597177.2009.10.18.23.33.21|-*@.
         /// <summary>
         /// Gets the def.
         /// </summary>
         /// <value>The def. from Settings.Default</value>
        // ReSharper disable MemberCanBePrivate.Global
        private static Set def{
          // ReSharper restore MemberCanBePrivate.Global
          get{
            return Set.Default;
          }
        }
      //;                        //<====================== Insertion POINT
      #endregion
  //#-@. private const     properties

Ora, per la giustificazione promessa, avere i membri vars in cima è la visione dei programmatori delle cose ovviamente non è la migliore per il client, ma è per questo che abbiamo Doc Tools giusto?

Mantenendo il codice rigido come questo sono sicuro che ha i suoi vantaggi nel fare le diff. Anche il layout generale ti costringe a pensare all'architettura che stai costruendo. Durante il flusso di lavoro inserisco gli identificatori Z_DOT tramite una macro che si basa sul fatto che fn sig sia presente e corretto, prima di colpire quella macro, dichiaro che sto esaminando correttamente il membro ecc. "È davvero quello che voglio fare "invece di inserire codice in qualsiasi punto della classe in cui mi trovo seduto e poi riordinarlo in un secondo momento (cioè se non stavo usando un sistema così rigido)

Il vantaggio principale ora è che posso scrivere macro che risolvono il codice con precisione, oltre a creare strumenti di analisi / refactoring / generazione esterni.

È molto utile avere questa suddivisione di secondo livello non solo per il modificatore di accesso, ma anche per var, proprietà backer, proprietà, comandi, eventi e funzioni (pure). Ti dà una visione-su-cose e ti fa pensare in termini di quella vista.

Collega alcune macro per portarti in ogni punto di inserimento nel file (che in realtà non ha quella cosa da grande freccia che ho messo lì per dimostrarlo) e sei a posto.

    
risposta data 15.01.2012 - 04:03
fonte
0

Penso che debba fare di più su: come ogni sviluppatore ama organizzare i membri della classe, in base a come ha in mente qualche modello di classe.

In primo luogo, è più comune iniziare con:

private
protected
public

criterio di ordinamento.

E, alla fine, mischia ciascun accesso, a seconda di cosa stanno facendo.

    
risposta data 04.01.2012 - 18:15
fonte