Come accederesti alle proprietà dell'oggetto dall'interno di un metodo dell'oggetto?[Chiuso]

StackOverflow https://stackoverflow.com/questions/126

  •  08-06-2019
  •  | 
  •  

Domanda

Qual è il modo "purista" o "corretto" per accedere alle proprietà di un oggetto dall'interno di un metodo oggetto che non sia un metodo getter/setter?

So che dall'esterno dell'oggetto dovresti usare un getter/setter, ma dall'interno faresti semplicemente:

Giava:

String property = this.property;

PHP:

$property = $this->property;

oppure faresti:

Giava:

String property = this.getProperty();

PHP:

$property = $this->getProperty();

Perdonatemi se il mio Java è un po' spento, è da un anno che non programmavo in Java...

MODIFICARE:

Sembra che le persone presumano che io stia parlando solo di variabili/proprietà private o protette.Quando ho imparato OO mi è stato insegnato a usare getter/setter per ogni singola proprietà anche se era pubblica (e in realtà mi è stato detto di non rendere mai pubblica alcuna variabile/proprietà).Quindi, potrei partire da un falso presupposto fin dall'inizio.Sembra che le persone che rispondono a questa domanda stiano forse dicendo che dovresti avere proprietà pubbliche e che quelle non hanno bisogno di getter e setter, il che va contro ciò che mi è stato insegnato e ciò di cui stavo parlando, anche se forse questo deve essere discusso come BENE.Questo è probabilmente un buon argomento per una domanda diversa però...

È stato utile?

Soluzione

Questo ha un potenziale di guerra religiosa, ma mi sembra che se stai usando un getter/setter, dovresti usarlo anche internamente: l'uso di entrambi porterà a problemi di manutenzione lungo la strada (ad es.qualcuno aggiunge il codice a un setter that esigenze da eseguire ogni volta che la proprietà viene impostata e la proprietà viene impostata internamente senza che il setter venga chiamato).

Altri suggerimenti

Personalmente ritengo che sia importante rimanere coerenti.Se hai getter e setter, usali.L'unica volta in cui accedo direttamente a un campo è quando la funzione di accesso ha molto sovraccarico.Potrebbe sembrare che tu stia gonfiando inutilmente il tuo codice, ma può sicuramente farti risparmiare un sacco di mal di testa in futuro.L'esempio classico:

In seguito, potresti voler cambiare il modo in cui funziona quel campo.Forse dovrebbe essere calcolato al volo o forse vorresti utilizzare un tipo diverso per il negozio di supporto.Se accedi direttamente alle proprietà, una modifica del genere può interrompere un'enorme quantità di codice in un solo colpo.

Sono abbastanza sorpreso da quanto sia unanime questo sentimento getters e i setter sono bravi e bravi.Suggerisco l'articolo incendiario di Allen Holub"Getter e setter sono malvagi".Certo, il titolo ha un valore scioccante, ma l'autore sostiene punti validi.

Essenzialmente, se lo hai getters E setters per ogni singolo campo privato, stai rendendo tali campi validi come pubblici.Sarebbe molto difficile cambiare il tipo di un campo privato senza effetti a catena per ogni classe che lo chiama getter.

Inoltre, da un punto di vista strettamente OO, gli oggetti dovrebbero rispondere a messaggi (metodi) che corrispondono alla loro (si spera) singola responsabilità.La stragrande maggioranza di getters E setters non hanno senso per i loro oggetti costitutivi;Pen.dispenseInkOnto(Surface) ha più senso per me di Pen.getColor().

Getter e setter incoraggiano inoltre gli utenti della classe a chiedere alcuni dati all'oggetto, eseguire un calcolo e quindi impostare qualche altro valore nell'oggetto, meglio noto come programmazione procedurale.Sarebbe meglio dire semplicemente all'oggetto di fare quello che stavi per fare in primo luogo;conosciuto anche come il Esperto di informazioni idioma.

Getter e setter, tuttavia, sono mali necessari al confine degli strati: UI, persistenza e così via.Accesso limitato agli elementi interni di una classe, come la parola chiave friend di C++, l'accesso protetto dal pacchetto Java, l'accesso interno di .NET e Modello di classe amico può aiutarti a ridurre la visibilità di getters e setter solo a chi ne ha bisogno.

Dipende da come viene utilizzata la proprietà.Ad esempio, supponiamo che tu abbia un oggetto studente con una proprietà name.Potresti utilizzare il metodo Get per estrarre il nome dal database, se non è già stato recuperato.In questo modo riduci le chiamate non necessarie al database.

Ora supponiamo che tu abbia un contatore intero privato nel tuo oggetto che conta il numero di volte in cui il nome è stato chiamato.Potresti non voler utilizzare il metodo Get dall'interno dell'oggetto perché produrrebbe un conteggio non valido.

PHP offre una miriade di modi per gestire questo problema, inclusi metodi magici __get E __set, ma preferisco getter e setter espliciti.Ecco perché:

  1. La convalida può essere inserita nei setter (e nei getter del resto)
  2. Intellisense funziona con metodi espliciti
  3. Non c'è dubbio se una proprietà è di sola lettura, di sola scrittura o di lettura-scrittura
  4. Il recupero delle proprietà virtuali (ovvero dei valori calcolati) ha lo stesso aspetto delle proprietà normali
  5. Puoi facilmente impostare una proprietà dell'oggetto che non è mai effettivamente definita da nessuna parte, e che quindi non viene documentata

Sto semplicemente esagerando qui?

Forse ;)

Un altro approccio sarebbe quello di utilizzare un metodo privato/protetto per eseguire effettivamente il recupero (caching/db/ecc) e un wrapper pubblico che ne incrementi il ​​conteggio:

PHP:

public function getName() {
    $this->incrementNameCalled();
    return $this->_getName();
}

protected function _getName() {
    return $this->name;
}

e poi dall'interno dell'oggetto stesso:

PHP:

$name = $this->_getName();

In questo modo puoi comunque utilizzare il primo argomento per qualcos'altro (come inviare un flag per stabilire se utilizzare o meno i dati memorizzati nella cache qui, forse).

Devo aver mancato il punto qui, perché dovresti usare un getter all'interno di un oggetto per accedere a una proprietà di quell'oggetto?

Portando tutto ciò alla conclusione, il getter dovrebbe chiamare un getter, che a sua volta dovrebbe chiamare un getter.

Quindi direi che all'interno di un oggetto il metodo accede direttamente a una proprietà, soprattutto visto che chiamare un altro metodo in quell'oggetto (che comunque accederà direttamente alla proprietà e poi la restituirà) è solo un esercizio inutile e dispendioso (o ho frainteso la domanda ).

Se per "purista" intendi "la maggior parte dell'incapsulamento", in genere dichiaro tutti i miei campi come privati ​​e quindi utilizzo this.field dall'interno della classe stessa, ma tutte le altre classi, comprese le sottoclassi, accedono allo stato dell'istanza utilizzando i getter.

direi che è meglio utilizzare i metodi di accesso anche all'interno dell'oggetto.Ecco i punti che mi vengono subito in mente:

1) Dovrebbe essere fatto nell'interesse di mantenere la coerenza con gli accessi effettuati all'esterno dell'oggetto.

2) In alcuni casi, questi metodi di accesso potrebbero fare di più che semplicemente accedere al campo;potrebbero eseguire alcune elaborazioni aggiuntive (è raro però).Se questo è il caso, accedendo direttamente al campo perderesti quell'ulteriore elaborazione e il tuo programma potrebbe andare storto se questa elaborazione dovesse sempre essere eseguita durante quegli accessi

Il metodo OO purista è evitare entrambi e seguire l'uno Legge di Demetra utilizzando il Dillo, non chiedere approccio.

Invece di ottenere il valore della proprietà dell'oggetto, which coppie strettamente le due classi, usa l'oggetto come parametro, ad es.

  doSomethingWithProperty() {
     doSomethingWith( this.property ) ;
  }

Dove la proprietà era di tipo nativo, ad es.int, utilizzare un metodo di accesso, denominarlo per il dominio problematico e non per il dominio di programmazione.

  doSomethingWithProperty( this.daysPerWeek() ) ;

Ciò consentirà di mantenere l'incapsulamento e qualsiasi post-condizione o invariante dipendente.Puoi anche utilizzare il metodo setter per mantenere eventuali precondizioni o invarianti dipendenti, tuttavia non cadere nella trappola di nominarli setter, torna al principio di Hollywood per la denominazione quando usi l'idioma.

ho scoperto che l'uso di setter/getter ha reso il mio codice più facile da leggere.Mi piace anche il controllo che dà quando altre classi usano i metodi e se cambio i dati la proprietà memorizzerà.

Campi privati ​​con proprietà pubbliche o protette.L'accesso ai valori dovrebbe passare attraverso le proprietà ed essere copiato in una variabile locale se verranno utilizzati più di una volta in un metodo.Se e SOLO se hai il resto della tua applicazione così totalmente ottimizzato, potenziato e altrimenti ottimizzato al punto che l'accesso ai valori passando attraverso le loro proprietà associate è diventato un collo di bottiglia (e questo non accadrà MAI MAI, te lo garantisco) dovresti anche iniziare considerare di lasciare che qualsiasi cosa diversa dalle proprietà tocchi direttamente le loro variabili di supporto.

Gli sviluppatori .NET possono utilizzare proprietà automatiche per applicare ciò poiché non è nemmeno possibile visualizzare le variabili di supporto in fase di progettazione.

Se non modificherò la proprietà utilizzerò a get_property() metodo pubblico a meno che non si tratti di un'occasione speciale come un oggetto MySQLi all'interno di un altro oggetto, nel qual caso pubblicherò semplicemente la proprietà e mi riferirò ad essa come $obj->object_property.

All'interno dell'oggetto per me è sempre $this->property.

Dipende.È più una questione di stile che altro e non esiste una regola fissa.

Posso sbagliarmi perché sono autodidatta, ma non utilizzo MAI le proprietà pubbliche nelle mie classi Java, sono sempre private o protette, in modo che il codice esterno debba accedere tramite getter/setter.È meglio per scopi di manutenzione/modifica.E per il codice interno alla classe...Se il metodo getter è banale, utilizzo direttamente la proprietà, ma utilizzo sempre i metodi setter perché, se lo desidero, potrei facilmente aggiungere codice agli eventi di attivazione.

Bene, sembra che con l'implementazione predefinita delle proprietà C# 3.0, la decisione venga presa per te;DEVI impostare la proprietà utilizzando il setter di proprietà (possibilmente privato).

Personalmente utilizzo il membro privato dietro solo quando non farlo causerebbe la caduta dell'oggetto in uno stato meno desiderabile, ad esempio durante l'inizializzazione o quando è coinvolta la memorizzazione nella cache/caricamento lento.

Mi piace la risposta di cmcculloh, ma sembra che la risposta più corretta sia quella di Greg Hurlmann.Usa sempre getter/setter se hai iniziato a usarli fin dall'inizio e/o sei abituato a lavorare con loro.

Per inciso, personalmente trovo che l'uso di getter/setter renda il codice più facile da leggere e da eseguire il debug in seguito.

Come affermato in alcuni commenti:A volte dovresti, a volte no.La parte migliore delle variabili private è che puoi vedere tutti i posti in cui vengono utilizzate quando cambi qualcosa.Se il tuo getter/setter fa qualcosa di cui hai bisogno, usalo.Se non ha importanza decidi tu.

Si potrebbe fare il caso opposto, ovvero se si utilizza getter/setter e qualcuno cambia getter/setter, deve analizzare tutti i punti in cui getter e setter vengono utilizzati internamente per vedere se incasina qualcosa.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top