Perché l'uso delle congiunzioni nei nomi dei metodi è una cattiva convenzione di denominazione? [chiuso]


12

Nel mio team, lavoriamo a stretto contatto con alcuni architetti del software. Approvano tutte le decisioni di progettazione dei nostri progetti, fanno alcune revisioni del codice, ecc.

I nostri progetti consistono principalmente in funzionalità back-end implementate in PHP usando il framework Symfony 2. Quindi sintatticamente, il codice, le convenzioni di denominazione e la struttura del progetto sembrano quasi identici a come sarebbe Java (Symfony 2 incoraggia tale struttura). Lo menziono perché nel nostro caso si applicano anche convenzioni specifiche di Java (se possibile).

Di recente, hanno suggerito qualcosa che trovo molto strano: tutti i metodi dovrebbero avere congiunzioni nel loro nome getEntityOrNull, ad esempio , setValueOrExceptionecc.

Una simile convenzione di denominazione mi sembra molto sbagliata, ma non riesco a trovare argomenti concreti o articoli / pagine online che lo mettano in discussione.

L'unica cosa che mi è venuta in mente è:

  • tali informazioni dovrebbero essere presenti nelle annotazioni del metodo, come @returno@throws
  • l'uso di congiunzioni ("e", "o" ecc.) nei nomi dei metodi di solito suggerisce che il principio di responsabilità singola non è adeguatamente rispettato

Quali sono alcuni altri argomenti concreti contro questa convenzione di denominazione?


generalmente, non puoi
moscerino l'

5
the use of conjunctions ("and", "or" etc.) in method names usually suggest that the Single Responsibility Principle is not properly respectedQuesto non è il caso degli esempi che hai elencato, in cui la congiunzione viene utilizzata per chiarire il meccanismo utilizzato per gestire i guasti, non per indicare che potrebbe fare una cosa o l'altra. Anche la funzione più definita può avere condizioni di errore legittime, ad esempio fare scoppiare uno stack vuoto.
Doval,

4
Considera: (1) utilizzando "opzionale" anziché "o null". "GetOptionalEntity" suona meglio al mio orecchio di "GetEntityOrNull". (2) la libreria di classi base .NET utilizza la convenzione secondo cui se si hanno due metodi che differiscono solo per ciò che lanciano, nominare quello che non può lanciare "TryBlah". Ad esempio, Int32.TryParsee Int32.Parse- entrambi analizzano una stringa in un numero intero, ma il primo restituisce un valore booleano che indica il successo e il secondo genera un errore.
Eric Lippert,

Non userei un suffisso per la variante di lancio, ma ne userei uno per la variante di ritorno nulla. Potrebbe essere Try..., ...OrNull, ...OrDefault. @EricLippert Questa non è l'unica convenzione in .net. Considerare Singlevs. SingleOrDefault, che è molto vicino OrNullall'OP suggerito.
CodesInChaos,

Risposte:


11

Probabilmente lo stanno facendo a causa di conflitti di denominazione. Presumo che non si possano avere due metodi nominati getEntity, uno che probabilmente genera un'eccezione e uno che ritorna null. Pertanto, è necessario nominarli di conseguenza.

Per uno, non mi piace la pratica di avere molti modi diversi di chiamare lo stesso metodo a meno che non stia eseguendo qualche alterazione che solo quella particolare classe può eseguire.

In altre parole, se si getValueOrNullsta semplicemente chiamando getValueOrException, catturando l'eccezione e in tal caso ritornando null, questo può essere eseguito dal chiamante. Raggruppa la classe con metodi che in realtà non forniscono nulla di utile. Preferirei piuttosto il getValue, e so che genera l'eccezione. Meglio ancora, preferirei sapere che tutti ottengono metodi potenzialmente generano eccezioni e nessuno di essi ritorna nullinvece in modo che il comportamento sia uniforme in tutto il mio progetto, o inversamente, tutti potenzialmente ritornano null, e so che il chiamante dovrebbe lanciare un'eccezione se che erano desiderati.

Tuttavia, è anche vero che non ne sei responsabile. Il mio consiglio è di sollevarlo, ma non sudare le cose meschine. In definitiva, la responsabilità di tali convenzioni di denominazione ricade sulle loro spalle, indipendentemente dal fatto che prendano o meno il tuo consiglio, e poiché sono i loro culi sulla linea, credo che sia una loro prerogativa dire di no, secondo la mia modesta opinione.


Se dovessi sceglierne solo uno, è meglio restituire null(o meglio ancora, un tipo Opzionale / Forse) poiché il lancio è relativamente costoso. La scrittura di un helper che verifica se un valore non è valido e genera non comporta costi eccessivi. Tuttavia, quando vuoi la versione no-throw, ingoiare l'eccezione non ti restituirà il colpo di prestazione che hai preso lanciandola.
Doval,

1
@Doval Un buon punto, e forse ancora più importante, le eccezioni dovrebbero essere eccezionali . Se stai spesso lanciando eccezioni, non le stai usando nel modo giusto. L'unico problema con la restituzione nullè che nullin alcuni casi potrebbe essere effettivamente un ritorno valido e quindi dovresti deviare dalla norma e lanciare un'eccezione in tali casi.
Neil,

3

Sebbene l'uso delle congiunzioni indichi spesso una violazione dell'SRP, in questo caso indica semplicemente il valore di ritorno del tipo di dati algebrico di un uomo povero che può essere uno di due valori, uno nullo un valore di "successo".

Stanno usando una specie di notazione ungherese per compensare le debolezze nel sistema dei tipi, vale a dire la mancanza di tipi non annullabili. In altre parole, non c'è modo di specificare nella tua @returnannotazione che la funzione non ritornerà mai null, e viceversa, non c'è modo di specificare nella tua @returnannotazione che la funzione potrebbe eventualmente tornare null.

Inoltre, credo che le @throwsannotazioni non siano obbligatorie in php, quindi l'assenza dell'annotazione non indica l'assenza di un'eccezione, anche se questo è meglio risolto rendendo l'annotazione obbligatoria nella tua guida di stile.

Date quelle limitazioni del linguaggio che stai usando, non è uno stile del tutto irragionevole.


2

Nel mio codice a volte creo coppie di metodi con nomi come getEntity () e getEntityOrNull (). Il nome chiarisce il comportamento previsto. Se getEntity () non trova alcuna entità, viene generata un'eccezione. getEntityOrNull () restituirà un valore null.

In questo modo, il codice chiamante diventa un po 'più chiaro. Se il codice chiamante deve avere un'entità, getEntity farà il trucco. Se l'entità è una specie di oggetto facoltativo, getEntityOrNull è il metodo di scelta.

La stessa cosa potrebbe essere realizzata con un solo metodo, ma questo sposta in parte l'onere del programma chiamante. Hai sempre bisogno di testare un null o hai bisogno di un blocco try / catch. In entrambi i casi è un codice aggiuntivo che deve essere duplicato ogni volta che viene chiamato il metodo.

Se i vostri architetti non utilizzano questo tipo di coppie di metodi, allora sì, metterei in dubbio la necessità del suffisso.

Non ho mai visto un metodo setValueOrException. Non riesco a pensare a un buon caso d'uso comune per quello.

Potresti considerare di chiedere agli architetti perché. Quelli che conosco sono sempre lieti di spiegare le loro decisioni. Spesso nei minimi dettagli (e talvolta in modo lancinante).


Che getEntity genererà un'eccezione in caso di fallimento non è per me chiaro, mi aspetterei un semplice NULL.
Elise van Looij,

1

I tuoi due argomenti sono validi. Ma se sono loro a decidere la convenzione di denominazione, cerca di non sentirti troppo male perché è qualcosa con cui non sei d'accordo.

Mentre ci sei, dovresti convincerli a non usare le porzioni "get" e "set" a meno che quei metodi non impostino o ottengano direttamente una variabile membro.

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.