quale stile di accesso membro è preferibile [duplicato]

0

lo scopo di oop utilizzando le classi è incapsulare i membri da outer space . Ho sempre letto che l'accesso ai membri dovrebbe essere fatto con metodi. per esempio:

template<typename T>
class foo_1 {
  T state_;
public:
  // following below
};

il più comune che faceva il mio professore era di avere un metodo get e set.

  // variant 1
  T const& getState() { return state_; }
  void setState(T const& v) { state_ = v; }

o così:

  // variant 2
  // in my opinion it is easier to read
  T const& state() { return state_; }
  void state(T const& v) { state_ = v; }

si supponga che state_ sia una variabile, che viene controllata periodicamente e non è necessario garantire che il valore (stato) sia coerente. C'è qualche svantaggio nell'accedere allo stato per riferimento? ad esempio:

  // variant 3
  // do it by reference
  T& state() { return state_; }

o anche direttamente, se dichiaro la variabile come pubblica.

template<typename T>
class foo {
public:
  // variant 4
  T state;
};

Nella variante 4 potrei persino assicurare la coerenza usando l'atomico c ++ 11.

Quindi la mia domanda è, quale preferisco ?, C'è uno standard di codifica che potrebbe declinare uno di questi pattern?

per alcuni codici vedi qui

    
posta itwasntpete 27.06.2013 - 01:54
fonte

3 risposte

10

Invece di inseguire le linee guida per le sfumature di implementazione suggerisco di cercare la motivazione di base per avere i setter e il getter in primo piano.

Una volta compreso il modo in cui aiutano, quali sono i casi in cui vi è una differenza pratica tra le forme e il modo in cui si manifesta, probabilmente puoi rispondere alla tua domanda per sempre.

E da quel momento capisci perché inseguire le linee guida anziché semplicemente scrivere il codice particolare in una forma sensata è una cattiva idea.

Inoltre, se inizi a scrivere effettivamente il codice OO invece delle solite strutture contraffatte relative al antipattern 'modello anemico', vedrai che un setter è una bestia estremamente rara, e anche i getter non elaborati non sono così comuni.

    
risposta data 27.06.2013 - 02:26
fonte
1

Non vedo motivi validi per scegliere tra 1 & 2 (anche se il getter dovrebbe essere const-qualificato) - basta scegliere uno stile e attenersi ad esso (o seguire lo stile della base di codice esistente).

Nella variante 3, stai ancora nascondendo alcune informazioni. Ad esempio, puoi passare a

template<typename T>
class foo {
  std::unique_ptr<T> state_;
public:
  foo() : state_(new T()) {}
  T& state() { return *state_; }
  T const& state() const { return *state_; }
};

senza influenzare i chiamanti. Quindi, potrebbe essere ancora utile. Perdi l'opzione di aggiungere la validazione (o la registrazione, o punti di interruzione, o ...) al setter più tardi se ne hai bisogno, almeno senza cambiare il codice cliente, quindi tieni presente che hai perso una certa flessibilità in cambio di un po 'meno di battitura.

Anche la variante 4 è perfettamente ragionevole: ad esempio, potrebbe non esserci motivo per limitare l'accesso ad alcuni aggregati POD. Nota che una classe con solo membri pubblici è solo un struct , quindi potresti chiamarla una. Tuttavia, ora sicuramente non può cambiare alcun dettaglio senza cambiare il client. Quindi, questo tipo di aggregato è solo un comodo pacchetto di dati, ma non riduce affatto l'accoppiamento.

    
risposta data 27.06.2013 - 11:39
fonte
1

Nessuna delle precedenti.

Proprietà sulle classi è un anti-pattern. Certo, hai sentito da qualche parte che accedere ai membri direttamente è una brutta cosa, quindi devi avvolgerli in un metodo o due per accedervi indirettamente ... ma pensa per un momento a quello che hai appena fatto - niente di reale.

Il problema inizia quando è necessario modificare uno di essi, il concetto di avvolgere la proprietà in un metodo in modo da poter modificare il tipo sottostante è semplicemente sbagliato. Puoi fare questo se sposti le proprietà in un metodo reale ma non se hai un metodo stupido che finge di essere il membro direttamente (cioè una proprietà).

ad es. Vedi questo post del blog per un esempio.

il punto è che, se si dispone di uno stato interno, non si dovrebbe mai consentire l'accesso a quello stato in termini dello stato stesso. Devi sempre pensare di accedere all'oggetto nel suo complesso.

Troppo spesso le lingue e gli standard (e i completamenti automatici dell'helper IDE) dicono che è necessario includere l'accesso ai membri in un metodo di proprietà, sono sbagliati. Non si dovrebbe mai nemmeno pensare ai membri come a qualcosa cui accedere, direttamente o indirettamente, dall'esterno della classe. Pensa alla classe e pensa a quale tipo di interfaccia dovrebbe supportare per fornire la sua funzionalità ai clienti.

    
risposta data 27.06.2013 - 13:36
fonte

Leggi altre domande sui tag