Regole pratiche per variabili locali vs membri

2

Ho sentito dire che le variabili dovrebbero essere dichiarate il più vicino possibile al loro utilizzo. Tuttavia, ho anche sentito che le variabili membro dovrebbero essere usate per descrivere qualcosa che è una caratteristica di una classe.

Trovo che questi due consigli a volte siano in conflitto. Ad esempio, supponiamo di avere una classe che analizza JSON utilizzando la libreria di jackson. L'oggetto parser di jackson che creo per consentire alla classe di essere in grado di analizzare JSON può essere considerato una "caratteristica" della classe? Senza l'oggetto parser la mia classe non può fare ciò che è stato progettato per fare.

Tuttavia, uso solo l'oggetto parser nella mia funzione di analisi principale - in quanto tale, potrei semplicemente creare una versione locale piuttosto che assegnargli un ambito di classe.

Forse quell'esempio è stato un po 'forzato, ma spero che trasmetta l'essenza della mia domanda. Cosa costituisce esattamente una "caratteristica" di una classe?

    
posta Adam 09.08.2016 - 01:37
fonte

5 risposte

6

member variables should be used to describe something that is a characteristic of a class

Sì e no. Linee guida come queste non dovrebbero essere prese troppo lontano, poiché potrebbero rapidamente trasformarsi in inutili discussioni filosofiche su ciò che effettivamente costituisce "una caratteristica di una classe". Penso che la regola sia utile come controllo rapido della sanità mentale: se un campo non può essere detto una caratteristica di una classe, allora probabilmente non dovrebbe essere un campo, o dovrebbe essere un campo in un altro classe. Ma il contrario non è vero. Anche se qualcosa potrebbe essere considerato una caratteristica di una classe che non segue dovrebbe essere un campo.

Vuoi sempre ridurre il numero di campi, quindi se qualcosa potrebbe essere un campo o un locale, lo vuoi come locale - indipendentemente dalla regola precedente. Quindi se il tuo parser può essere un locale dovrebbe.

    
risposta data 09.08.2016 - 12:19
fonte
3

Per il tuo esempio sopra (il parser JSON), ecco alcuni pensieri. Puoi estenderli ad altri casi d'uso, si spera.

Hai ragione che lo stesso parser non è un membro della classe. Così puoi istanziarlo localmente ovunque ti serva. Tuttavia, questo ha due problemi:

  1. potresti avere la necessità di iniettare nella classe per scopi di test, quindi forse è più semplice farne un membro e popolarlo tramite il costruttore?
  2. potrebbe volerci molto tempo per inizializzarsi, nel qual caso creare un'istanza e referenziare sarebbe più veloce, e l'essere un membro sarebbe più pratico.

A questo punto hai membri della classe che fanno intuitivamente la classe (ad esempio x e y coordinate per una classe Point ) e membri di supporto (ad esempio il parser sopra). Normalmente non mi preoccuperei di questo.

Potresti rinforzare la divisione, forse, facendo derivare la classe da un'interfaccia che fornisce metodi che fanno riferimento ai membri (ad esempio getX() , getY() , ma nessun getter del parser. Non è necessario ottenere il parser, vorrei suggerire).

Ma il mio istinto è che non mi preoccuperei. Gli interni della tua classe sono davvero interni. Non mi piacciono i getter perché voglio dire a una classe di fare qualcosa - non tirare fuori i membri e farlo da solo. Nota che potresti voler cambiare la parte interna della classe e la tua interfaccia rimarrà la stessa. Di conseguenza, i membri della classe sono lì per supportare l'implementazione che preferisci per fare in modo che la classe faccia quello che vuoi in modo efficace / efficiente di cui hai bisogno.

    
risposta data 09.08.2016 - 11:06
fonte
2

In parole povere:

  • I membri sono considerati parte dello stato di una classe
  • Una classe è considerata coesiva quando i suoi metodi accedono allo stato della classe
  • Se il parser verrà utilizzato solo nella funzione parser, potresti anche passarlo come parametro.
  • Se vuoi cambiare il parser durante la vita della classe tramite l'iniezione con un metodo setParser, allora dovrebbe essere una variabile membro e parte dello stato della classe.
risposta data 09.08.2016 - 13:52
fonte
1

Per approfondire ciò che altri stanno dicendo, considera la vita dell'oggetto. Considerare ora le vite dei membri dell'oggetto.

Se questi non sono uguali o molto simili, allora alcuni membri che hanno vite (sostanzialmente) più brevi rispetto all'istanza nel suo complesso.

Questo è un indicatore che ci sono diverse responsabilità in corso, che potrebbero indicare la divisione della classe (o l'uso di una variabile locale invece di una variabile membro).

Questa linea guida può aiutarti a capire quando hai qualcosa che non è coeso come un'unità come indicato dalla loro collocazione (all'interno della stessa classe).

    
risposta data 10.08.2016 - 01:04
fonte
0

I've also heard that member variables should be used to describe something that is a characteristic of a class.

Hai provato a trovare questa definizione?

Se il parser è logicamente stateless e completamente incapsulato, renderlo un campo è praticamente un ottimizzazione delle prestazioni. Rendendolo un locale è un ottimizzazione della memoria.

La migliore definizione OOP è qui: link

    
risposta data 09.08.2016 - 11:27
fonte

Leggi altre domande sui tag