6

Chiediti cosa pensi di questi due diversi approcci: metodi di overload e nomi di metodi lunghi/dettagliati.Best practice per la firma del metodo: sovraccarico e lungo nome

Aggiornamento: Sto cercando un modello generale/procedura ottimale. Quello che segue è solo un esempio.

data una struttura organizzativa con relazioni padre/figlio

> OrgUnit 
> - OrgUnit 
> -- OrgUnit 
> -- OrgUnit 

due metodi Quale utilizzare lo stesso codice in grandi parti per portare i bambini per un elemento XML.

// 1) only 1 level down children 
getSubOrgUnits() 

// 2) all levels down 
getSubOrgUnits(boolean includeChildren) 

// 3) alternative naming of 1) 
getDirectSubOrgUnits() 

// 4) alternative naming of 2) 
getAllSubOrgUnits() 

Quindi 1 e 2 è utilizzando i parametri E 3 e 4 sta usando senza parametri di denominazione.

Cosa vorresti e perché? Considera anche che 1) e 2) possono ottenere parametri aggiuntivi che risultano in cose come getChilds (true, false, null) ma anche 3) e 4) possono ottenere nomi come getDirectSubUnitsExcludeSome()

Può essere specifico JAVA ma un più ampio la vista su questo è apprezzata.

risposta

8

A mio parere, l'utilizzo del nome del metodo dettagliato è una soluzione migliore.

  • è più comprensibile, il codice richiede meno commenti
  • E 'più facile da mantenere, è possibile cambiare l'implementazione senza impattare firme esistenti. È ancora possibile aggiungere una nuova firma, senza regressione.

Ma attenzione, in alcune situazioni è preferibile aggiungere alcuni parametri

Esempio 1

private List<Element> getElementsByType(MyTypeEnum type); 

public List<Element> getElementsOfType1(); 
public List<Element> getElementsOfType2(); 
public List<Element> getElementsOfType3(); 

/* VS */ 

public List<Element> getElementsByType(MyTypeEnum type); 

Entrambe le implementazioni sono buone, dipende da voi, dalle dimensioni del MyTypeEnum, sulla sua capacità di aumentare di dimensioni. Cosa vuoi esporre? Vuoi che il chiamante di getElements*** sia in grado di ottenere tutti i tipi di Element?

Esempio 2

public void log(Level l, String s, Exception e); 

/* VS */ 

public void logInfo(String s); 
public void logWarning(String s); 
public void logError(String s, Exception e); 

In questo caso, la seconda parte è migliore. Perché è più leggibile, facile da capire al primo sguardo. E poiché quando si effettua il login nel livello INFO e WARNING, non è necessario specificare uno Exception. Quindi specializzare il metodo è una buona cosa. Tuttavia, è importante mantenere il metodo public void log(Level l, String s, Exception e); pubblico e non privato perché potrebbe essere utile utilizzare questo metodo generico in alcuni casi.

Conclusione

Dipende dalla situazione, ma se avete la possibilità di aggiungere metodi specifici, con nomi verbose, che si specializzano un comportamento bersaglio, farlo.

+0

Buona risposta, anche buona Esempio da un caso di utilizzo reale con registrazione. Grazie. – LukeSolar

0

Prima di tutto, chiamerei il metodo getChildren(), non getChilds(). :)

Se si dispone di più livelli, perché non introdurre un argomento per il livello di profondità?

// Get children up to depthLevel 
getChildren(final int depthLevel) 

// For convenience 
getChildren() 

Nel caso di un metodo senza parametri, aggiungere informazioni significative, in modo che altri sviluppatori so se si sta tornando tutti o solo di primo livello.


Edit: OP ha chiesto: "?. Quindi, in generale quale approccio si usa, perché, che utilizzano casi potrebbe condividere i tuoi pensieri su questo un po '"

Questo è molto basato sull'opinione. Come affermato da @OldCurmudgeon, molte librerie che elaborano strutture ad albero usano metodi dedicati per accedere al livello secondario. Questo va bene, finché lo fai regolarmente. D'altra parte, l'introduzione di un argomento depthLevel offre maggiore potenza se si desidera accedere a un particolare livello della struttura. Questo dipende molto dal tuo solito caso d'uso.

Quindi, se è molto probabile che sia necessario ottenere il primo figlio di un oggetto spesso, introdurre getFirstChild() e getChildren(). Se è più probabile che tu acceda più spesso a livelli più profondi dei tuoi dati o se hai bisogno di accedere a livelli dedicati, introduci un parametro di profondità.

+0

ciao, grazie. Ho aggiornato la domanda. Quindi, in generale, quale approccio usi, perché, quali casi d'uso? potresti condividere i tuoi pensieri su questo un po '. – LukeSolar

+0

Ho aggiunto ulteriori informazioni alla mia risposta. Tuttavia, le domande basate su opzioni sono disapprovate qui, quindi attenzione, altrimenti la domanda potrebbe essere chiusa. – user1438038

0

Il solito modo questo tipo di struttura sarebbe stato gestito è con:

// Used when you KNOW there is only one child. 
getFirstChild(); 
// Used when there may be many children. 
getChildren(); 

Questo è il modello usato da XOMgetChildElements e getFirstChildElement a camminare la struttura di un file XML.

È sempre possibile utilizzare:

thing.getFirtsChild().getChildren(); 

per accedere livelli più profondi.

+1

Sto cercando uno schema/best practice più generale. In qualche modo ho la sensazione che le "vecchie" librerie di java sfruttino pesantemente gli overload di metodi (booleano activateX, booleano activateY, int someParam) che può portare a firme come do (boolean, boolean, int) dove devi leggere il codice sorgente (e devi averlo;)) - dove le librerie "più recenti" sono più simili a doWithXAndY (int param) - spero di potermi chiarire. – LukeSolar

+0

La documentazione è fondamentale, quando si tratta di metodi con molti argomenti. Quando si introduce un nuovo metodo per ogni argomento letteralmente, questo non migliora le cose. Invece di avere un metodo con molti argomenti, avrai molti metodi con pochi argomenti. Stai solo spostando il problema. – user1438038

2

Tutto si riduce al sapore.

Come pratica generale si può andare con il "Il meno parametri meglio è". È sia conveniente in termini di chiarezza del codice che consente di risparmiare memoria dello stack (non molto, ma ogni bit è importante nel lungo periodo).

Avere nomi diversi aiuta anche a completare automaticamente.

Per esempio vorrei andare per

GetAllSubOrgUnitsList() 
GetFirstSubOrgUnitsList() 

La ragione di questo, dopo ottiene, la prima lettera che scrivo identificherà quello che voglio.

Come hai detto, se non puoi avere un nome intuitivo, puoi aggiungere parametri di default.

Nel tuo esempio,

GetDirectSubUnitsExcludingSome() 

vorrei sostituirlo con un set minimo di parametri

GetFilteredSuborgUnits(ISuborgFilter aFilter); 

E poi, dall'architettura, chiedere agli sviluppatori di implementare i propri filtri personalizzati. Un filtro può chiedere la profondità gerarchica, una certa proprietà ecc. (Sei l'architetto, decidi tu).

Quindi, in breve: KISS!

Anche se GetAllSuborgUnits() fornisce lo stesso risultato con GetFilteredSubOrgUnits (null), dare un'alternativa rapida e chiara a un comportamento è meglio che avere un nome/insieme di parametri complicato. Dopo tutto, i licenziamenti non sono sempre una brutta cosa :).

+0

Ho scelto ToYonos risposta perché dà esempi migliori. Il parametro del filtro è una buona idea, ma viene anche trattato nell'altra risposta con un enum. Grazie mille. – LukeSolar

+0

Nessun problema, felice di aiutare. – MichaelCMS