JavaRush /Java Blog /Random-IT /Getter/Setter. Cattivo. E punto
angelina
Livello 5

Getter/Setter. Cattivo. E punto

Pubblicato nel gruppo Random-IT
Articolo di Egor Bugaenko 19 settembre 2014 | Pubblicato in: Core Java Getter/Setter.  Cattivo.  E il punto - 1 Questo vecchio dibattito è stato avviato da Allen Holub nel suo famoso articolo, nel 2003, Perché i metodi getter e setter sono malvagi : i getter/setter sono un anti-pattern e dovremmo evitarli, o è qualcosa che non possiamo fare? saranno sicuramente necessari nella programmazione orientata agli oggetti. Aggiungo i miei due centesimi a questa discussione. Il succo del testo seguente è questo: getter e setter sono cattive pratiche; coloro che li usano non hanno scuse. Ma ancora una volta, per evitare malintesi, non sto affatto suggerendo che l'uso di get/set debba essere evitato ove possibile. NO. Sto dicendo che non li hai nemmeno lasciati avvicinare al tuo codice . Getter/Setter.  Cattivo.  E il punto - 2Cosa ne pensi di questa affermazione? Degno della tua attenzione? Utilizzi il pattern get/set da 15 anni e sei un rispettato architetto Java? E non vuoi nemmeno ascoltare queste sciocchezze da uno sconosciuto? Beh... capisco i tuoi sentimenti. Mi sono sentito allo stesso modo finché non mi sono imbattuto nel libro di David West "Object Thinking": è il miglior libro sulla programmazione orientata agli oggetti che abbia mai letto. Quindi per favore. Calmati e cerca di capire cosa sto cercando di spiegare. Oggetto di controversia Ci sono diversi argomenti contro gli "accessori" (un altro nome per getter e setter) nel mondo orientato agli oggetti. E sono tutti argomenti molto corretti. Diamo loro una rapida occhiata. Chiedi, non dire : Allen Holub dice: "Non chiedere le informazioni di cui hai bisogno per svolgere un lavoro; 'chiedi' all'entità che ha tali informazioni di fare il lavoro per te." Principio di incapsulamento violato : un oggetto può essere smontato da altri oggetti perché sono in grado di incorporare qualsiasi dato nell'oggetto, tramite setter. Un oggetto semplicemente non può incapsulare il proprio stato in modo sufficientemente sicuro perché chiunque può modificare quello stato. Dettagli di implementazione rivelati : se puoi ottenere un oggetto da un altro oggetto, allora stiamo facendo troppo affidamento sui dettagli di implementazione del primo oggetto. Se domani cambia (ad esempio il tipo di risultato), allora dovremo cambiare il codice. Tutte le giustificazioni di cui sopra hanno certamente senso, ma qui non si coglie il punto più importante. Malinteso di base La maggior parte dei programmatori crede che un oggetto sia una struttura dati con metodi. Cito l'articolo di Bozhidar Bozhanov: Getters e Setter non sono malvagi. Ma la maggior parte degli oggetti per i quali vengono creati getter e setter contengono semplicemente dati. Questo malinteso è il risultato di un enorme malinteso! Gli oggetti non "memorizzano solo dati". Gli oggetti non sono strutture dati con metodi allegati. Questo concetto di "archiviazione dei dati" deriva dalla programmazione orientata agli oggetti e dai linguaggi procedurali, in particolare C e COBOL. Lo ripeterò ancora: un oggetto non è solo una raccolta di elementi di dati e funzioni che li manipolano. Un oggetto non è un oggetto dati. Cosa poi? Palla e cane Nella vera programmazione orientata agli oggetti, gli oggetti sono esseri viventi, proprio come te e me. Sono organismi viventi, con il proprio comportamento, proprietà e ciclo vitale. Può un organismo vivente avere un setter? Puoi attaccare (“impostare”) una palla a un cane? Non pensare. Ma questo è esattamente ciò che fa il pezzo di codice seguente:
Dog dog = new Dog();
dog.setBall(new Ball());
Allora, come ti piace? Riesci a togliere (“prendere”) la palla dal cane? Bene, supponiamo che tu possa. Nel caso l'avesse mangiato e tu l'avessi operata. In questo caso sì, potrai prendere (“prendere”) la palla dal cane. Sto parlando proprio di questo:
Dog dog = new Dog();
Ball ball = dog.getBall();
Oppure un esempio ancora più ridicolo:
Dog dog = new Dog();
dog.setWeight("23kg");
Riesci a immaginarlo nella vita reale? Ti sembra che tu scriva tutti i giorni? Se sì, allora sei un programmatore procedurale. Ammettilo. Ecco cosa dice David West a pagina 30 del suo libro: Il primo passo per trasformare uno sviluppatore procedurale di successo in uno sviluppatore di obiettivi di successo è una lobotomia. Hai bisogno di una lobotomia? Ne avevo decisamente bisogno e l'ho ottenuto leggendo il libro di West "Object Thinking". Pensiero oggettivo Inizia a pensare come un oggetto e rinominerai immediatamente questi metodi. Ecco cosa potresti ottenere:
Dog dog = new Dog();
dog.take(new Ball());
Ball ball = dog.give();
Adesso trattiamo il cane come un vero animale che può toglierci la palla e restituircela se glielo chiediamo. Per ogni evenienza, noto che il cane non può restituire NULL. I cani semplicemente non sanno cosa sia NULL! Il pensiero oggettivo (pensiero) rimuove immediatamente i riferimenti NULL dal tuo codice. Getter/Setter.  Cattivo.  E il punto - 3
Un pesce chiamato Wanda (1988) di Charles Crichton
Inoltre, il pensiero oggettivo porterà all’immutabilità di un oggetto, come il “peso del cane” nel nostro esempio. Dovresti riscrivere il codice in questo modo:
Dog dog = new Dog("23kg");
int weight = dog.weight();
Un cane è un organismo vivente immutabile che non permetterà a nessuno al di fuori di cambiarne il peso, la taglia, il nome, ecc. Può "dire", su richiesta, il suo peso o il suo nome. Non c'è niente di sbagliato nei metodi pubblici che espongono query per determinate proprietà "interne" di un oggetto. Ma questi metodi non sono “getter” e non dovrebbero mai ricevere il prefisso “get”. Non "usciamo" dal cane. Non capiamo il suo nome. Le chiediamo di dirci il suo nome. Vedi la differenza? Non stiamo nemmeno parlando di semantica qui. Differenziamo l'approccio procedurale alla programmazione da quello orientato agli oggetti. Nella programmazione procedurale lavoriamo con i dati, li manipoliamo, li otteniamo, li impostiamo e, se necessario, li cancelliamo. Siamo noi a comandare e i dati sono solo una componente passiva. Un cane per noi non è niente: semplicemente “contiene dati”. Non ha una vita propria. Possiamo ottenere (ottenere) liberamente tutto ciò di cui abbiamo bisogno da esso e inserirvi (impostare) qualsiasi dato. Ecco come funzionano (funzionano) C, COBOL, Pascal e altri linguaggi procedurali. E nel mondo orientato agli oggetti la situazione è completamente opposta. Qui trattiamo gli oggetti come organismi viventi, con una propria data di nascita e un momento di morte, con una propria personalità e abitudini, se vogliamo. Possiamo chiedere al cane di fornirci un dato (ad esempio il suo peso) e lui potrà restituircelo. Ma ricordate sempre che il cane è la componente attiva. Decide lei cosa succede dopo la richiesta. Ed ecco perché è assolutamente sbagliato che i metodi di un oggetto inizino con set o get. E non si tratta nemmeno di violare l’incapsulamento, come molti pensano. Si tratta del fatto che o stai pensando come un oggetto o stai ancora scrivendo in COBOL con la sintassi Java. PS . E sì, potresti chiedere: "E JavaBeans, JPA, JAXB e molte altre API Java che dipendono da get/set?" Che dire della funzione integrata in Ruby che semplifica la creazione di accessori? Beh, cosa posso dirti... sei sfortunato. È molto più facile rimanere nel mondo primitivo del COBOL procedurale che comprendere e abbracciare il meraviglioso mondo degli oggetti reali. PPS _ Ho dimenticato di dire che sì, anche l'inserimento di dipendenze tramite un setter è un terribile anti-pattern. Ma ne parleremo più approfonditamente nel prossimo post! Articolo originale
Commenti
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION