C'è una buona ragione per rendere le funzioni pure non pubbliche?

25

Ho avuto un piccolo dibattito in corso con un collega. In poche parole, c'è un buon motivo per nascondere / incapsulare le funzioni che sono pure?

Per "puro" intendo la definizione di Wikipedia :

  • Restituisce sempre gli stessi risultati dallo stesso input. (Per il gusto di questa discussione Foo Create(){ return new Foo(); } è considerato impuro se Foo non ha semantica del valore.)
  • Non usa lo stato mutabile (tranne le variabili locali) o I / O.
  • Non produce effetti collaterali.
posta Telastyn 26.09.2014 - 16:41
fonte

4 risposte

76

Una funzione pura potrebbe essere ancora un dettaglio di implementazione. Sebbene la funzione non possa causare alcun danno (dal punto di vista di non violare invarianti / contratti importanti), esponendo sia l'autore che gli utenti di quella classe / modulo / pacchetto perdono. L'autore perde perché ora non può rimuoverlo anche se l'implementazione cambia e la funzione non è più utile per lui. Gli utenti perdono perché devono setacciare e ignorare funzioni extra che non sono rilevanti per l'utilizzo dell'API per comprenderlo.

    
risposta data 26.09.2014 - 17:02
fonte
42

La domanda è indietro.

Non cerchi un motivo per rendere una funzione non pubblica. È una mentalità sbagliata per cominciare (secondo me). Il ragionamento dovrebbe andare dall'altra parte.

In altre parole - non chiedere "perché lo renderei privato?". Chiedi: "perché dovrei renderlo pubblico?"

In caso di dubbio, non esporlo. È un po 'come il rasoio di Ockham - non moltiplicare i titoli oltre la necessità.

EDIT: affrontare i controguardi portati da @Telastyn nei commenti (per evitare discussioni estese):

I've heard that over time, and even espoused it for quite some time, but in my experience, things tend to be too private.

Sì, a volte è un dolore se una classe è aperta per ereditarietà, ma non puoi sovrascrivere alcuni metodi privati (il cui comportamento ti piacerebbe modificare).

Ma protected sarebbe sufficiente - ed è ancora non pubblico.

It leads to a lot of code duplication and overhead to get at "things that shouldn't be public" yet are accessed indirectly anyways.

Se diventa problematico, rendilo semplicemente pubblico! C'è la necessità di cui stavo parlando :)

Il mio punto è che non dovresti farlo nel caso (YAGNI e tutti).

Tieni presente che è sempre più semplice rendere pubblica una funzione privata rispetto a quella precedente. È probabile che quest'ultimo rompa il codice esistente.

    
risposta data 26.09.2014 - 17:23
fonte
6

Non credo che la decisione di nascondere / incapsulare una funzione debba dipendere dalla sua purezza. Solo perché una funzione è pura non significa che gli esterni debbano saperlo. È interessante notare che se la funzione è pura e intende essere pubblica forse non è nemmeno necessario essere un membro di istanza dell'interfaccia, forse è più adatto come statico. Ma tutto ciò dipende ancora dall'intento del contratto e in questo caso dal raggruppamento logico di funzionalità, non dalla purezza della funzione.

    
risposta data 26.09.2014 - 17:08
fonte
5

Le classi devono aderire al principio di responsabilità singola . Mentre una classe potrebbe aver bisogno di chiamare altre funzionalità per raggiungere i suoi obiettivi, dovrebbe solo esporre le funzioni che fanno parte della sua unica responsabilità.

Questo è solo un esempio di un caso in cui la visibilità potrebbe causare un problema.

Considera una classe che ottimizza i widget. Forse come parte del suo codice di ottimizzazione ha bisogno di qualche funzione di utilità che analizzi una stringa: forse ha bisogno di trasformare il nome del widget in un modo che le funzioni di stringa standard non supportano.

Poiché questa è una funzione pura (la stringa arriva, la trasforma in qualche modo, restituisce una nuova stringa), potrebbe essere pubblica o privata senza conseguenze. O potrebbe?

Se lo rendi pubblico, ora la tua classe ha due responsabilità: widget di ottimizzazione, e trasformazione delle stringhe. Ciò viola l'SRP e può causare problemi se altre classi si affidano alla funzione. Dato che questo è qualcosa che pensi sia usato solo all'interno della classe, forse cambi la sua interfaccia o visibilità. Ora le classi in altre parti del sistema sono rotte.

Tenendo la funzione privata, nessuno ha mai la possibilità di fare affidamento su un codice che non fa parte della singola responsabilità della classe.

    
risposta data 26.09.2014 - 17:29
fonte

Leggi altre domande sui tag