Come fai a mantenere SOA SECCO?

5

Nella nostra organizzazione, ci siamo spostati su una "architettura orientata ai servizi". Per fare un esempio, supponiamo di dover recuperare un oggetto "Preventivo". Questa citazione ha un mittente, un destinatario, numeri di telefono, contatti, indirizzi email e altre informazioni sulla posizione. In altre parole, un oggetto Citazione è costituito da molti altri oggetti.

Quindi, sembra che abbia senso fare un "servizio di recupero preventivo". Nella nostra situazione, abbiamo raggiunto questo obiettivo creando una soluzione .NET e scrivendo il servizio. L'API del servizio è simile a questa (in pseudo-codice):

Function GetQuote(String ID) Returns Quote

Quindi, finora tutto bene. Ora, quando questo servizio viene consumato, per mantenere le cose "disgiunte", stiamo creando essenzialmente un duplicato dell'oggetto Quote e la mappatura dalla versione QuoteService del Preventivo nella versione del preventivo del consumatore. In molti casi, queste classi avranno le stesse identiche proprietà.

Quindi, se il servizio di quotazione è consumato da altre 5 applicazioni, avremmo 6 definizioni di cosa sia una "citazione". Uno per ciascun consumatore e uno per il servizio. Questo sembra sbagliato. Pensavo che il codice doveva essere SECCO, ma sembra che il nostro metodo di SOA ci stia costringendo a creare tonnellate di definizioni di classi duplicate. Cosa stiamo sbagliando o la duplicazione del codice è solo un "male necessario" di SOA?

    
posta TaylorOtwell 17.11.2011 - 20:09
fonte

5 risposte

6

JGWiessman è corretto in quanto la mancanza di DRYness nei proxy generati automaticamente non è costosa, perché non si mantiene il codice generato dal client. Cambialo sul server, aggiorna i tuoi riferimenti sui client, lavoro fatto.

Tuttavia, esiste un'alternativa, se sia il client che il server sono .NET. È possibile inserire tutti gli oggetti in un assembly separato, a cui fanno riferimento sia il client che il server. Se quindi si genera automaticamente il client codice, è semplicemente un'interfaccia, usando gli stessi oggetti che il server usa .

Fai questo solo se gli oggetti che stai condividendo sono muti e non includi alcun codice sul lato server, altrimenti stai esponendo quel codice al tuo client.

Se sia il client che il server utilizzano la stessa versione di .NET, puoi fare un ulteriore passo avanti e include l'interfaccia esclusivamente per configurazione . Ma devi stare attento qui. L'interfaccia sul lato server richiede l'attributo ServiceContract e quindi fa riferimento all'assembly ServiceModel, quindi se le versioni sono diverse, puoi metterti nei guai.

    
risposta data 17.11.2011 - 21:12
fonte
1

Non dovresti essere handcoding la definizione duplicata nel consumatore. Utilizzare invece uno strumento come Visual Studios per importare un riferimento al servizio Web una classe proxy generata dal computer. C'è un codice ripetuto, ma è generato da una macchina e non devi mantenerlo, basta reimportare quando cambia la definizione del master.

    
risposta data 17.11.2011 - 20:52
fonte
0

Se tutto il resto fallisce, sono sempre stato in grado di ottenere il codice DRY tramite la generazione del codice. pdr ha una buona soluzione per quando quello che vuoi fare si adatta a ciò che Microsoft ti offre, ma se non lo fai puoi sempre fare la tua generazione di codice.

Quindi puoi gestire cose come la generazione di codice per i client che non usano .NET, facendo esplicite regole codificate come "Il client B ottiene la versione client generica di Quote eccetto l'indirizzo email, ma aggiunge un campo di codice homing piccione viaggiatore", (piuttosto che aggiungere manualmente nuovi campi a tutti i servizi del client 302) ecc.

    
risposta data 17.11.2011 - 21:55
fonte
0

Personalmente preferisco un approccio leggermente diverso. Sono convinto che in aziende di grandi dimensioni, il dominio aziendale è troppo grande, quindi il DDD è la strada da percorrere. Quando le entità sul lato servizio (o qualsiasi altro a cui il servizio tier) sono definite in un modo richiesto per il servizio , la logica viene definita per recuperarle dalla persistenza e eseguire una logica di qualsiasi tipo, fornisce sempre un'entità mappata (nota come "contesto vincolante", "dto", "contratto dati" ecc.) che è la più idonea per dimensione e internals "fratello" per l'entità originale, ma non gonfia di i dettagli che non saranno mai esposti al mondo esterno.

Quindi, quando il servizio deve essere esposto, il contratto del servizio passa a una DLL separata (libreria leggera che è possibile spedire a un client, nessuna logica all'interno, solo interfacce). Spedisci anche una libreria contenente entità a un cliente. Questi due descrivono distintamente il contratto di conversazione e il formato dei messaggi.

Se sento che ci sono troppe poche coppie da spedire ora, e hanno una struttura diversa , allora questa non è più SOA, perché il tuo servizio blackbox ora sta dicendo troppo su se stesso ai consumatori e inoltre i consumatori chiedono a blackbox-service di cambiarne la forma. In questo caso di solito utilizzo REST per ridurre i problemi con i contratti di dati o sovrascrivere i metodi di serializzazione sugli oggetti DTO e, a seconda dello StreamingContext fornito, fornire una forma diversa dell'entità.

    
risposta data 17.11.2011 - 23:25
fonte
0

Questa non è un'architettura SOA ottimale.

Il fornitore di servizi dovrebbe fornire lo stesso servizio per tutti i consumatori.

I consumatori dovrebbero utilizzare ciò di cui hanno bisogno dalle Risposte e ignorare ciò di cui non hanno bisogno.

Non vedo perché ogni consumatore debba aver bisogno della propria versione del servizio.

Anche nel caso di un requisito di sicurezza che solo alcuni utenti sono autorizzati a vedere determinati dati è possibile inserire tali dati in un gruppo facoltativo e semplicemente non inviarlo a utenti non autorizzati. Conservando così una singola interfaccia per tutti i client.

    
risposta data 18.11.2011 - 03:12
fonte

Leggi altre domande sui tag