WCF / SOA - Perché dovrei creare oggetti parametro per richieste semplici

12

La nostra azienda sta avviando un'iniziativa SOA piuttosto ampia. Stiamo facendo molte cose bene: c'è una buona comunicazione; denaro per gli strumenti, se del caso; e abbiamo apportato alcune buone competenze per aiutarci nella transizione.

Stiamo cercando di sviluppare standard che possiamo seguire come gruppo e uno degli standard proposti mi dà fastidio un po ':

Abbiamo standardizzato sul modello in cui ogni operazione richiede un oggetto richiesta e restituisce un oggetto risposta.

Mi rendo conto che questo è più o meno un approccio standard per molte persone, ma sto chiedendo perché dovrei preoccuparmi? (non sono così bravo con la saggezza ricevuta, ho bisogno di perché).

La maggior parte dei servizi che fornirò sono semplici recuperi di metadati organizzativi. Ad esempio, trova la politica di sicurezza per un particolare utente. Questo ha bisogno di un ID utente e nient'altro. Lo standard mi dice che dovrei racchiudere questa richiesta in un oggetto e avvolgere la politica restituita in un oggetto risposta.

Il mio disagio è amplificato da uno sguardo al WSDL generato dai nostri contratti. WCF genera automaticamente i messaggi di richiesta e risposta e avvolge anche l'oggetto richiesta / risposta.

Capisco perfettamente che se stai facendo una richiesta complessa, allora è necessario un oggetto di input complesso. Questo è quello che faresti anche se i servizi non fossero coinvolti.

La mia domanda è: perché dovrei racchiudere automaticamente richieste e risposte quando:

  • Rende i servizi semplici meno espressivi
  • Lo faresti comunque per un servizio complesso
  • WCF crea comunque un messaggio di richiesta / risposta

Ho trovato i seguenti argomenti a favore di questo approccio:

Supporta il controllo delle versioni consentendo l'inserimento di parametri facoltativi nell'oggetto richiesta.

Nel passato, ho fatto un bel po 'di COM, e considererei questo quasi un anti-pattern per il controllo delle versioni. Per alcune cose, suppongo che sarebbe d'aiuto, ma mi aspetto che dove sarebbe utile, hai già un oggetto parametro comunque.

Consente di isolare dati e comportamenti comuni in una classe base

Questo ha un peso con me.

Guida le persone lontano da un comportamento in stile RPC e verso un comportamento di messaggistica

Ho letto questo sul sito di Microsoft e l'ho ascoltato dal nostro guru, ma non ho ancora una chiara idea di cosa significano o perché è prezioso. È che le interfacce dall'aspetto naturale fanno sì che le persone tendano a dimenticare di chiamare un servizio remoto?

Sto cercando di refactoring le firme di forse 300 metodi, quindi questa è una quantità non banale di dolore. Sono un grande fan della coerenza nelle implementazioni, quindi sono disposto ad accettare il dolore, mi aiuterà solo a sapere che alla fine ne varrà la pena.

    
posta Andy Davis 15.10.2011 - 22:46
fonte

2 risposte

3

Penso che il versioning sia probabilmente l'argomento migliore. Quando hai un contratto operativo esistente come

int GetPersons(int countryId);

che desideri migliorare, ad es. da un altro filtro in seguito

int GetPersons(int countryId, int age);

Dovresti scrivere un nuovo contratto operativo e con un nuovo nome poiché deve essere unico. Oppure manterrai il nome e pubblichi una nuova v2 del tuo servizio con la vecchia v1 ancora in giro per la compatibilità con le versioni precedenti.

Se si avvolge il parametro in un oggetto, è sempre possibile estenderlo con i parametri predefiniti / facoltativi e tutti i client esistenti non saranno interessati quando si riutilizza lo stesso contratto operativo.

Tuttavia, vorrei anche nominare i tuoi oggetti in modo appropriato. Anche se avvolge solo un int, se inizi con IntMessage o qualcosa di simile non ti stai facendo un favore estendendolo. Dovresti chiamarlo per es. PersonFilter dall'inizio, il che significa che devi pensare un po 'a ciò che questa chiamata di servizio dovrebbe aspettarsi come parametro semanticamente e quindi cosa dovrebbe fare. Forse (e questo è molto vago forse) che aiuterà lo sviluppo dei servizi giusti e manterrà un'API di dimensioni decenti.

It allows common data and behavior to be isolated to a base class

È qualcosa con cui essere cauti. I contratti di ereditarietà e di dati non vanno molto d'accordo. Funziona, ma dovrai specificare tutti i sottotipi noti del contratto che potrebbero andare oltre il filo, altrimenti il serializzatore del contratto di dati non riesce a lamentarsi dei tipi sconosciuti.

Ma ciò che potresti fare (ma ancora probabilmente non dovrebbe, sono ancora indeciso su questo) è riutilizzare gli stessi messaggi tra diversi servizi. Se si inseriscono i contratti di dati in una dll separata, è possibile condividerli tra client e servizio e non è necessario effettuare la conversione tra tipi quando si chiamano servizi diversi che prevedono sostanzialmente lo stesso messaggio. Per esempio. crei un PersonFilter e lo invii a un servizio per ottenere un elenco di filtri di persone e quindi a un altro servizio e avere gli stessi oggetti sul client. Però non riesco a trovare un buon esempio del mondo reale e il pericolo è sempre che un'estensione dei contratti dati non sia abbastanza generale per tutti i servizi che usano questo contratto.

Nel complesso, a parte il controllo delle versioni, non riesco davvero a trovare la ragione killer per farlo in quel modo.

    
risposta data 16.10.2011 - 00:46
fonte
0

Le note di Martin Fowler sull'oggetto Data Transfer sono appropriate qui, penso.

When you're working with a remote interface, such as Remote Facade (388), each call to it is expensive. As a result you need to reduce the number of calls, and that means that you need to transfer more data with each call. One way to do this is to use lots of parameters. However, this is often awkward to program - indeed, it's often impossible with languages such as Java that return only a single value.

The solution is to create a Data Transfer Object that can hold all the data for the call. It needs to be serializable to go across the connection. Usually an assembler is used on the server side to transfer data between the DTO and any domain objects.

Lo stesso potrebbe valere per le richieste. Per quanto riguarda RPC, e perché è pessimo:

Is it that natural looking interfaces make people tend to forget that they are calling a remote service?

Penso sia vero, ma non il motivo principale. Un altro motivo per evitare RPC è che può incoraggiare clienti e servizi strettamente accoppiati.

    
risposta data 11.03.2012 - 00:49
fonte

Leggi altre domande sui tag