È utile usare l'incapsulamento nel linguaggio di programmazione dinamico, scritto e interpretato?

0

Per quello che so, l'incapsulamento è utile perché:

  1. se si utilizza direttamente un attributo e si cambia il suo tipo in un linguaggio tipizzato statico, è necessario modificare tutto il codice che utilizza la classe. Al contrario, se hai dichiarato getter e setter per quell'attributo, non devi farlo
  2. nasconde il funzionamento interno della tua classe, utile se, ad esempio, stai offrendo un'API
  3. evita che un'altra classe che eredita la tua classe sovrascriva attributi o metodi

Le mie considerazioni sul linguaggio di programmazione dinamico digitato e interpretato sono:

  1. poiché i tipi sono dinamici, non è necessario incapsulare la classe per questo motivo
  2. puoi vedere il codice di un linguaggio interpretato, quindi penso che non ci sia un modo per nascondere realmente la tua API
  3. questo potrebbe essere un problema quando questo non è intenzionale, ma la mia opinione è che dovrebbe essere meglio fare attenzione alla sovrascrittura involontaria invece di limitare di default questa possibilità. Python è un buon esempio: se dichiari, ad esempio, il nome di un attributo o metodo che lo avvia con un doppio trattino basso, puoi dichiararlo anche in una classe ereditata, ma sono minacciati come due variabili distinte anche se hanno lo stesso nome (grazie delnan)

un nome di metodo che inizia con un carattere "_" genera un avviso se sovrascritto da un metodo di una classe ereditaria.

Mi manca qualcosa di importante?

    
posta Marco Sulla 31.05.2013 - 15:16
fonte

2 risposte

21

Sì, ti manca qualcosa.

L'incapsulamento è spesso descritto con metafore di "nascondimento" o recitazione "difensiva", come se i programmatori fossero tuoi nemici e dovevi agire furtivamente e subdolamente per difenderti contro le loro cattive intenzioni. Questo è a volte utile; per esempio, se programmi framework estremamente popolari che devono mantenere la compatibilità in un numero enorme di situazioni e versioni, inizi a pensare ai tuoi utenti come barbari ignoranti il cui unico scopo nella vita è quello di causarti problemi con le loro irragionevoli richieste di "Ma funzionava! " oppure "Ma posso vedere che è un array internamente! Perché, perché, perché non mi permetti di accedere direttamente agli elementi ??"

Tuttavia , il caso normale è che il livello che usa il tuo codice sia programmato dalla stessa persona del tuo stesso livello: te stesso. Quindi il punto non è in realtà per nascondere informazioni da altre routine e dai loro creatori, ma per liberare il suo chiamante dal doverlo capire . Il trucco è rendere possibile la scrittura di routine di livello superiore senza conoscere i dettagli. L'illusione cognitiva che se hai creato qualcosa da te stesso, ovviamente capirai che tutto ciò che fa è estremamente comune ed estremamente strong; ampie parti dell'ingegneria del software sono dedicate a mitigare le conseguenze di questo errore di pensiero. Se si programma una subroutine, ma è necessario sapere come funziona internamente per poterla utilizzare correttamente, allora si potrebbe anche non avere una subroutine, perché lo sforzo mentale necessario non è effettivamente ridotto: il codice sembra pulito e modulare, ma in realtà non lo è.

Ecco perché separiamo grandi quantità di codice in piccole partizioni: perché una piccola quantità di codice è più facile da capire di una grande quantità e, soprattutto, due piccoli bit di codice correttamente disaccoppiati sono più facili da capire di un paio di volte il doppio dimensione, perché le interdipendenze all'interno della parte più ampia aggiungono uno sforzo cognitivo. Se non evitiamo questo sforzo in più, prima o poi supererà la nostra capacità di comprendere l'intero sistema, e presto diventerà irrinunciabile.

    
risposta data 31.05.2013 - 15:30
fonte
2

Stai dimenticando due cose.

Innanzitutto, l'incapsulamento è prima di tutto quello di mantenere la quantità di accoppiamento tra i moduli bassa in modo strutturato, ad esempio, mantenendo il codice modulare. L'incapsulamento corretto separa le interfacce dalle implementazioni e la possibilità di modificare i processi interni senza toccare l'interfaccia va ben oltre i semplici getter / setter e copre più di semplici tipi di ritorno. Prendi, ad esempio, un rettangolo. Esistono due possibili rappresentazioni: (left, top, right, bottom) o (left, top, width, height) . Né è meglio, ma entrambi possono essere più adatti per determinate situazioni. Se crei getter / setter per tutte e sei le proprietà (sinistra, destra, alto, basso, larghezza, altezza), puoi modificare la rappresentazione interna in 5 minuti, senza toccare nessun altro codice.

Un motivo più importante, tuttavia, è che l'incapsulamento limita l'ambito di campi e metodi. Ciò significa che quando si desidera modificare un campo privato, è sufficiente prendere in considerazione la classe contenente; se è pubblico, devi controllare l'intera base di codice per possibili regressioni. Per estensione, ragionare sul codice correttamente incapsulato è più facile del codice in cui tutto è apertamente accessibile da qualsiasi luogo.

    
risposta data 31.05.2013 - 16:57
fonte