Quale design API per la memorizzazione di dati generici in un formato più specifico?

8

for Nel progetto a cui sto lavorando inviamo messaggi sui widget sulle code dei messaggi, serializzandoli sulle code come XML. Lo schema XML contiene tag per le proprietà comuni a tutti i tipi di questi messaggi widget, come il tipo di widget, il nome del comando e la destinazione. Può anche contenere un elenco di coppie chiave-valore di dimensioni arbitrarie per consentire la memorizzazione di proprietà che sono rilevanti solo per un tipo specifico di messaggio widget. La classe WidgetMessage incapsula questi dati e le classi WidgetMessageXmlWriter e WidgetMessageXmlReader forniscono la serializzazione da e verso XML.

Ho creato alcune classi che incapsulano messaggi specifici, ad esempio FooPlaySoundMessage per un widget "Foo" o BarSetLightPatternMessage per un widget "Bar". Ognuno di essi ha un metodo di istanza ToWidgetMessage e un metodo statico FromWidgetMessage per la conversione in e dalla classe WidgetMessage . Ogni famiglia di messaggi eredita da una classe astratta per quel tipo di widget, ad es. FooMessage e BarMessage , che a loro volta ereditano dalla classe WidgetMessageMapping ; questo memorizza le proprietà dei messaggi comuni e i metodi protetti utilizzati dalle sottoclassi per la conversione. Nessuna di queste classi eredita da WidgetMessage poiché non desidero che ereditino la relativa proprietà della raccolta valori-chiave e i metodi associati , quindi la necessità di conversione piuttosto che la semplice trasmissione.

Mi piace la semplicità della mia API (ad es. FooPlaySoundMessage msg = FooPlaySoundMessage.fromWidgetMessage(widgetMessage) ), ma il fatto che io debba usare metodi protetti in una classe base per condividere funzionalità e metodi statici per esporlo, mi chiedo se ci debba essere una classe separata o due coinvolti qui (simile a WidgetMessageXmlWriter e WidgetMessageXmlReader ). D'altra parte, ho pensato che parte del punto di OOP fosse raggruppare insieme dati e metodi e quindi evitare "oggetti dati stupidi" .

Quindi, ho un'idea giusta aggiungendo metodi di conversione ai miei oggetti dati, o questa funzionalità dovrebbe essere estratta in un'altra classe?

Aggiornamento:

Penso che in tutti i dettagli sopra del mio attuale tentativo di progettazione non ho spiegato abbastanza chiaramente il problema che sto cercando di risolvere.

In sintesi, ho una classe DTO "generica" che ha alcune proprietà strongmente tipizzate e una collezione di coppie chiave-valore per memorizzare altri dati personalizzati. Voglio avere alcune classi DTO specializzate per ogni set di dati personalizzati che memorizzino tutti gli stessi dati del DTO generico, tranne che con le coppie chiave-valore sostituite da proprietà strongmente tipizzate. Qual è il miglior design per la conversione tra questi due tipi di DTO?

    
posta Robert Johnson 21.02.2013 - 01:15
fonte

1 risposta

1

Se FooPlaySoundMessage sa come riprodurre il suono e anche come mappare se stesso in un formato di coda dei messaggi, potresti dire che la classe ha più di una responsabilità. Se delega direttamente il suono effettivo a una classe diversa, il tuo FooPlaySoundMessage è fondamentalmente un oggetto di trasferimento dati. Mettere le mappature comuni in una classe base condivisa mi sembra soddisfacente in questo caso.

Probabilmente lo separerei comunque. Gli oggetti per il trasferimento dei dati hanno in genere un codice minimo o nullo, è possibile visualizzare FooPlaySoundMessage come uno.

A un certo punto potresti dover trasmettere gli stessi dati con altri mezzi o qualche altro formato (forse JSON?). Potresti YAGNI per ora e poi separarlo.

Probabilmente creerò una classe di gestore di messaggi che analizzi le parti comuni, rileva il tipo di messaggio e quindi delega a un parser specifico, ad es. FooPlaySoundXmlMessageParser. In caso di dubbio, preferisci la composizione all'eredità.

    
risposta data 15.03.2013 - 09:34
fonte

Leggi altre domande sui tag