Messaggi Xml: un tipo per regolarli tutti?

1

Il mio lavoro coinvolge un progetto che ha molti pezzi diversi che tutti hanno bisogno di comunicare tramite messaggi XML. Ci sono due scuole di pensiero su come questi messaggi dovrebbero essere organizzati.

In realtà questi messaggi possono contenere centinaia di campi e un sacco di annidamenti, ma cercherò di semplificare. Quindi diciamo che il progetto è per un meccanico che lavora su vari veicoli. I messaggi sono richieste di cose come dipingere una macchina, cambiare l'olio e sostituire i freni.

Opzione 1: utilizza tipi diversi per ciascun messaggio.

Con questa configurazione, ogni richiesta ha il proprio tipo di primo livello e ogni tipo ha i suoi membri:

Quindi riceveremmo una richiesta simile a questa:

<PaintRequest>
   <vin>123</vin>
   <color>red</color>
</PaintRequest>

O questo:

<OilChange>
   <vin>123</vin>
   <oilType>synthetic</oilType>
</OilChange>

O questo:

<BrakeReplacement>
   <vin>123</vin>
   <brakeType>cheap</brakeType>
</BrakeReplacement>

L'argomento di questi messaggi è che tu sai esattamente cosa aspettarti da ciascun messaggio in base al suo tipo. A BrakeReplacement è garantito un membro di brakeType che puoi quindi utilizzare per eseguire un'azione.

Opzione due: utilizza un tipo per ogni messaggio.

Con questo approccio, c'è solo un tipo di primo livello, e quel tipo conterrà membri diversi a seconda del tipo di richiesta che viene fatta. Quindi avresti richieste che assomigliano a questo:

<Vehicle>
   <vin>123</vin>
   <color>red</color>
   <oilType>null</oilType>
   <brakeType>null</brakeType>
</Vehicle>

O questo:

<Vehicle>
   <vin>123</vin>
   <color>null</color>
   <oilType>synthetic</oilType>
   <brakeType>null</brakeType>
</Vehicle>

O questo:

<Vehicle>
   <vin>123</vin>
   <color>null</color>
   <oilType>null</oilType>
   <brakeType>cheap</brakeType>
</Vehicle>

Questi messaggi possono contenere ogni campo, ma in realtà la maggior parte dei campi sarà nullo e verranno compilati solo i campi pertinenti a quella specifica richiesta. Saprai quali campi dovrebbero essere nel messaggio in base a quale endpoint la richiesta è arrivata.

L'argomento di questo approccio è che devi gestire un solo tipo e in teoria una richiesta può contenere più tipi di azioni (anche se nel nostro caso specifico, non è mai così).

La mia domanda è: entrambi questi approcci soddisfano o violano i principi di progettazione / progettazione / OOP del software?

Capisco entrambi gli argomenti e vedo pro e contro per ogni approccio. Ma sto cercando di trovare una fonte più "ufficiale" del mio modesto parere.

L'unica cosa che posso pensare è Principio di sostituzione di Liskov , in quanto il secondo approccio usa gli stessi tipi per diversi richieste, quindi non è possibile sostituire un'istanza con un'altra. Quindi se qualcuno invia una richiesta di OilChange all'endpoint PaintRequest, non sapremo che è sbagliato fino a quando non è tardi.

Ma penso che sia un allungamento, poiché l'LSP si applica al tipo di ereditarietà, non alle istanze.

Per quel che vale, queste richieste arrivano sugli endpoint REST e quindi vengono inviate a un processo Java di back-end. Quel processo Java utilizza JAXB per convertire l'XML in classi Java.

    
posta Kevin Workman 12.05.2016 - 17:17
fonte

3 risposte

3

Vorrei favorire il primo approccio per 2 motivi:

  • Per quanto ho capito, dipingere un veicolo, cambiare i suoi freni o sostituire l'olio sono tre operazioni distinte che sono fatte separatamente (nel tempo, nello spazio). Quindi non è la preoccupazione dell'endpoint che gestisce il pennello sapere che i freni devono essere sostituiti da quelli meno costosi (o peggio ancora, da quelli null ).
  • Se la tua azienda si evolve e decide di mettere anche posti nelle proprie vetture, gli endpoint esistenti rimangono invariati, viene creato solo uno nuovo insieme a un nuovo tipo di messaggio (la manutenzione è più semplice in quanto non è necessario ridistribuire una versione completamente nuova a ogni endpoint).
risposta data 12.05.2016 - 21:41
fonte
1

Questo

Use one type for every message

sembra controintuitivo e potenzialmente problematico per me. Vorrei molto piuttosto specificare messaggi diversi per diversi scenari e inviarli a diversi endpoint.

I tuoi endpoint dovranno rifiutare i messaggi che non si aspettano, ma poiché dovrebbero respingere comunque i messaggi mal formati, non penso che ci sia un gran problema.

Il grande guadagno sarà che se modifichi la struttura di un messaggio OilChange , è ragionevole preoccuparsi solo del codice che analizza e usa il messaggio OilChange e l'oggetto corrispondente. Se si dispone di un messaggio globale, qualsiasi modifica a ciò potrebbe influire potenzialmente su ogni percorso di codice. Una buona suite di test coprirà questo scenario, concesso, ma limitare l'ambito dei tuoi messaggi ridurrà il numero di potenziali problemi che affronti.

    
risposta data 12.05.2016 - 17:26
fonte
0

Perché non provare qualcosa del genere:

<Vehicle>    
</OilChange>    
</PaintRequest>    
<BrakeReplacement>
      <vin>123</vin>
      <brakeType>cheap</brakeType>    
</BrakeReplacement> 
</Vehicle>

È facile mantenere tale xml. Hai un solo file XML senza HOTCH POTCH nel tuo file. Se in futuro i requisiti cambiano e ritieni di poter fornire più di un servizio alla volta, non è necessaria alcuna modifica nel tipo di file.

    
risposta data 13.05.2016 - 12:50
fonte

Leggi altre domande sui tag