È un odore di codice se un metodo privato lo chiama pubblico?


25

È un odore di codice chiamare metodo pubblico in metodo privato della stessa istanza di oggetto?


AAMOI hai un esempio specifico?
ottobre

No, non attualmente. Ho appena ricordato un caso di cui ho discusso con i miei colleghi. Volevo avere qualche opinione anche qui.
Eimantas,

5
Di solito riesco a capire un acronimo per il contesto, ma AAMOI dovevo assolutamente cercare
Carson Myers,

@Carson - hai trovato qualcosa?
Eimantas,

4
Come questione di interesse
Carson Myers,

Risposte:


32

Nessun cattivo odore. Questo potrebbe essere necessario, perché sospetti che sia sbagliato? Un metodo a livello atomico è un'entità indipendente che svolge un'attività. Finché svolge un'attività chiunque abbia accesso ad essa può chiamarla per completare l'attività.


Sono d'accordo. Alcuni metodi forniscono funzionalità utili sia per gli interni che per i chiamanti esterni. Una bandiera rossa potrebbe essere se il metodo pubblico fosse molto specifico per l'implementazione interna, ma anche in questo caso non tutte le classi intendono nascondere i propri interni. Ho spesso un livello "strumento" di struttura dati sotto un livello di tipo astratto contenitore, ad esempio - in questo modo posso riutilizzare parte del codice della struttura dati per altre strutture dati sottostanti altri contenitori.
Steve314,

19

Odore di codice? Sì, non proprio male, ma un buon indicatore del fatto che la classe potrebbe avere troppe responsabilità.

Prendilo come un segno che la classe potrebbe aver bisogno di essere suddivisa in diversi oggetti, i metodi privati ​​non dovrebbero davvero aver bisogno di chiamare metodi pubblici dello stesso oggetto, sicuramente in un design OO pulito.

Naturalmente, una volta che hai ispezionato la classe e i motivi della chiamata al metodo sono chiari, può essere un uso perfettamente ragionevole, in generale ti aspetteresti che i metodi di utilità per la classe siano privati, ma se uno è abbastanza utile per essere pubblico e utilizzato con altri metodi, mi aspetterei, in generale, che anche questi metodi siano pubblici.

Come per tutti gli odori di codice, questa è una motivazione per un'ulteriore ispezione del codice, razionalizzazione e forse refactor, ma non causa di allarme.


5
+1 per "non causa di allarme". Troppe volte vediamo un 'odore' e andiamo istantaneamente in modalità refactor senza pensare.
Michael K,

+1 per SRP. Mi sono appena imbattuto in un caso in cui un decoratore non stava lavorando perché la classe decorata stava chiamando la propria funzione pubblica, aggirando il decoratore. La soluzione: dividere la classe in due e iniettare la dipendenza decorata.
Jon Hulka,

18

Potrebbe portare a spiacevoli sorprese se qualcuno che non ha letto il codice sorgente di questa classe tenta di sottoclassarlo e ignora il metodo pubblico. Se questa è una vera preoccupazione dipende ovviamente dalla tua situazione. Forse dovresti prendere in considerazione l'idea di rendere pubblico il metodo o persino la lezione finale.


Perché? Se un metodo pubblico sovrascritto porta a spiacevoli sorprese, importa davvero chi ha chiamato il metodo?
user281377,

4
Sì lo fa. Se l'override di un metodo pubblico interrompe un altro metodo pubblico, posso ignorare anche quell'altro metodo. Se si rompe un metodo privato, posso ....?
Kim,

5
Una spiacevole sorpresa derivante dalla sostituzione di un metodo pubblico è un odore di codice in sé. Una puzza di codice, in realtà.
Larry Coleman,

Kim: se il metodo è pubblico, devi supporre che anche altre classi lo chiamino ...
user281377

@Larry: esattamente! Un metodo privato (che di solito contiene ipotesi specifiche dell'implementazione) che chiama uno pubblico rende più probabile che l'override del metodo pubblico rompa le cose.
Kim,

5

Non credo che possiamo genaralizzare.

Tutto dipende molto dal contesto.

Potrei avere, per esempio, un metodo di utilità pubblica in una classe che viene utilizzato da altre classi e anche un metodo privato nella stessa classe.


5

No. Cos'altro si dovrebbe fare in quel caso? Rendere pubblico il metodo privato o privato? Copia-Incolla il codice dal metodo pubblico a quello privato?


Oppure fai delegare il metodo pubblico a un (nuovo) metodo privato che viene invocato dall'altro metodo privato. Ma perché preoccuparsi?
Lawrence Dol,

4

NO , nessun cattivo odore qui.

se implementiamo l'interfaccia di una coda con List, è un cattivo odore chiamare semplicemente le funzioni List appropriate per ottenere facilmente l'implementazione della coda?

se hai qualcosa e vuoi convertirlo in qualcos'altro (come wrapper), allora non è un cattivo odore, la riusabilità del codice con il modello di progettazione agisce a livello di funzione (una funzione è un oggetto?)


2

So che questo è un vecchio post, ma è qualcosa su cui ho discusso sul lavoro. Lo "considero" un odore di codice e non riesco a capire perché tu abbia mai voluto farlo. Se un metodo privato deve chiamare un metodo pubblico, il contenuto del metodo pubblico deve essere preso e inserito in un metodo privato, che entrambi i metodi possono quindi chiamare. Perché?

  1. Il metodo pubblico può contenere test non necessari una volta eseguito internamente il codice. Potrebbe ricevere un UserObj e, ad esempio, voler testare le autorizzazioni dell'utente.

  2. Dopo una chiamata pubblica, potrebbe essere necessario bloccare l'oggetto, se si utilizza il threading, quindi internamente, non si vorrebbe richiamare a un metodo pubblico.

  3. A mio avviso, ho maggiori probabilità di introdurre errori circolari e loop infiniti e eccezioni mem.

  4. Design semplice e semplice, cattivo e "pigro". I metodi pubblici forniscono accesso al mondo esterno. Non c'è motivo di tornare fuori quando sei già dentro.


1
Cosa succede se il metodo pubblico esistente viene chiamato da molte altre classi? Renderlo privato lo spezzerà. Ricorda che i metodi pubblici sono chiamati da altre classi per altri motivi, non solo per questa classe. un po 'perché esistono metodi pubblici.
Michael Durrant,

Ho affermato che "il contenuto del metodo pubblico dovrebbe essere preso e inserito in un metodo privato ..." Il metodo pubblico rimarrà, ma effettuerà una chiamata al nuovo metodo privato. Come qualsiasi altro metodo privato che deve riutilizzare la stessa funzionalità.
Mark Graham,

Quindi stai aggiungendo un altro metodo per nessun altro motivo che - beh, perché hai dichiarato che questo è un "odore di codice". I metodi inutili hanno un odore di codice peggiore.
gnasher729,

Mi dispiace, ma non ho elencato solo diversi motivi sopra. Gran parte del codice che scrivo riguarda i sistemi aziendali, molte classi sono limitate agli utenti in base al ruolo. Molti metodi pubblici testano le autorizzazioni e i parametri dell'utente. Perché mai dovrei voler richiamare allo stesso metodo pubblico per riutilizzare la sua funzionalità e testare nuovamente le autorizzazioni dell'utente?
Mark Graham,

Nella mia vita non ho mai avuto bisogno di chiamare un metodo pubblico da uno privato. Sembra e mi sembra molto sbagliato. Sono davvero sorpreso che la maggior parte della gente pensi che vada bene.
Trappola il

2

Immagina il contrario. Sei in un metodo privato e hai bisogno di funzionalità in un metodo pubblico E se non potessi chiamare quel metodo pubblico da quello privato. Cosa faresti?

  • Creare un metodo privato duplicato? No
  • Creare un metodo pubblico speciale per l'occasione? No
  • Chiamare un metodo privato speciale che può chiamare metodi pubblici? No
  • Una sorta di super che può farlo? No

La risposta è chiaramente che quando si desidera la funzionalità in un metodo pubblico, si dovrebbe essere in grado di chiamare quel metodo da metodi di questa classe o da altre classi.


1

Nel mio codice creo spesso getter a carico lento, vale a dire l'oggetto viene inizializzato la prima volta che viene richiesto e successivamente riutilizza lo stesso oggetto istanziato. Tuttavia, un oggetto istanziato usando un carico lento implica che potrebbe non essere necessariamente istanziato in un dato punto. Piuttosto che avvolgere la testa attorno alla sequenza di chiamate in modo tale che io sappia che quell'oggetto è già istanziato o che ripete lo stesso codice di un carico pigro all'interno di un altro metodo, chiamo semplicemente il caricatore pigro ogni volta che ho bisogno di quell'oggetto.

Così come puoi usare i metodi pubblici in modo intelligente, puoi anche usarli in modo errato. Un esempio di questo potrebbe essere un metodo pubblico che elabora i suoi parametri prima di chiamare un altro metodo privato. Sarebbe un errore chiamare quel metodo pubblico casualmente semplicemente perché hai gli stessi parametri. L'errore è sottile ma è un errore di progettazione più di ogni altra cosa e richiede che tu impari a gestire i parametri del metodo interno anziché i parametri del metodo pubblico.

Quindi, per rispondere alla tua domanda, non è certamente un codice errato se lo usi correttamente.


1

La domanda che devi porti è perché la tua classe ha le stesse necessità dei clienti della tua classe? Di solito una classe ha esigenze molto diverse dai suoi clienti. Quindi sì, questa è un'indicazione che hai entrambi

(a) ha esposto pubblicamente qualcosa che dovrebbe essere privato; o

(b) il comportamento della classe non è abbastanza ristretto (si pensi al principio di responsabilità singola).

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.