L'elenco dei parametri di un metodo contiene oggetti o identificatori di oggetti?

10

I nostri team stanno discutendo la seguente discussione:

Diciamo che abbiamo i seguenti due metodi:

public Response Withdraw(int clubId, int terminalId,int cardId, string invoice, decimal amount);

public Response Withdraw(Club club, Terminal terminal,Card card, string invoice, decimal amount);

che cosa viene inviato over-the-wire sono solo gli id.

un lato dice che il primo metodo è corretto, perché abbiamo solo gli id del terminale e del club, e dovrebbe essere chiaro che non abbiamo nient'altro, questo è il mio approccio.

l'altro lato dice che il secondo metodo è corretto perché è più flessibile.

Abbiamo familiarità con l'idea del parametro oggetto, l'altro lato pensa anche che il parametro oggetto debba avere gli oggetti come proprietà.

Qual è l'approccio corretto?

Forse c'è un terzo approccio ancora migliore?

    
posta Mithir 03.03.2013 - 13:27
fonte

3 risposte

10

La risposta dipende dal contesto.

Se il client prevede che tutti questi oggetti siano già disponibili , utilizzerei i parametri dell'oggetto. Altrimenti, il loro codice sembrerà più complicato di quanto non debba essere. (Ad esempio, avranno chiamate come club.getId() , per esempio.)

Se il client avrà solo gli ID disponibili facilmente, allora forse il secondo approccio è migliore, in quanto potresti non volere che il client debba assemblare / caricare tutti quegli oggetti se davvero hai solo bisogno gli id.

Un'opzione è di fornire entrambi i metodi , in modo che il client possa scegliere quale utilizzare (dato che ciò non ingombra la tua API)

In generale i parametri dell'oggetto sono più estensibili, poiché se in futuro hai bisogno di un altro pezzo di dati per eseguire il lavoro, non è necessario introdurre un altro metodo che utilizzi tali informazioni aggiuntive.

Infine, le firme dei metodi non dovrebbero essere dettate dalle specifiche di ciò che fa il metodo (nel tuo caso, che cosa va esattamente sul filo). L'API dovrebbe avere un senso astratto, quindi se l'implementazione cambia, non sei fregato.

    
risposta data 03.03.2013 - 14:07
fonte
13

Il primo approccio è indicativo di Primitive Obsession . Poiché stai passando intarsi e stringhe, è molto facile per il programmatore commettere un errore (ad esempio, passando un clubId al parametro terminalId). Ciò si tradurrà in bug difficili da trovare.

Nel secondo esempio, è impossibile passare una mazza quando ci si aspetta un terminale - questo ti darebbe un errore in fase di compilazione.

Anche così, guarderei ancora string invoice . Una fattura è davvero una stringa? Cosa significa amount ? Questo è più probabilmente un valore monetario.

Hai menzionato nella tua domanda "che cosa viene inviato over-the-wire sono solo gli id.". Questo è corretto, ma non lasciare che questo requisito infanghi il tuo dominio.

La migliore spiegazione che ho visto a favore di questo approccio era nella regola 3 di Object Calisthenics :

An int on its own is just a scalar, so it has no meaning. When a method takes an int as a parameter, the method name needs to do all of the work of expressing the intent. If the same method takes an Hour as a parameter, it’s much easier to see what’s going on. Small objects like this can make programs more maintainable, since it isn’t possible to pass a Year to a method that takes an Hour parameter. With a primitive variable the compiler can’t help you write semantically correct programs. With an object, even a small one, you are giving both the compiler and the programmer additional info about what the value is and why it is being used.

    
risposta data 03.03.2013 - 13:42
fonte
2

Non c'è una risposta giusta a questo. Qualsiasi opzione potrebbe essere giusta per il lavoro. Beh, quasi in ogni modo, l'argomento della fattura ha sollevato un solco sulla mia fronte, non ho idea di cosa sia leggendo il codice.

Se si invia un ID, entrambi i sistemi devono essere strettamente accoppiati a ciò che rappresenta. ClubID è la chiave nella tabella dei club. Più al punto che sia caller che callee devono concordare che cosa viene chiamata la tabella Clubs e in quale database si trova. Se non vuoi o non puoi imporre quel vincolo, passerai l'oggetto usando una descrizione comune, nativa, serializzata, xml, nome = valore qualunque, un file ini:)

Che come hai identificato ti costerà "over the wire". Evitarlo semplicemente inviando l'identificatore ti costa altrove. Quindi quale ti fa più male, ora (o potrebbe essere più tardi ...) è l'indicatore di buono vs cattivo.

    
risposta data 03.03.2013 - 16:53
fonte

Leggi altre domande sui tag