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.