Suggerimenti di progettazione per convertitori in Java

3

Sto provando un set di convertitori che convertirà un oggetto in un modulo più vecchio. E ci sono diversi oggetti che vengono convertiti. Per forma più vecchia intendo la modifica dei valori di alcuni campi e in caso di oggetti file che apportano modifiche tali che il nuovo file sia conforme allo schema precedente, ecc.

A convertObjectAToOldFormat(A a);
B convertObjectBToOldFormat(B b);

Devo creare una classe per ciascuno di questi convertitori? Oppure posso inserirli tutti in una singola classe ed esporre l'interfaccia ai client? O c'è qualche disegno che gestirà meglio questo?

La lingua utilizzata è Java

    
posta Praveen Hassan 18.05.2015 - 14:38
fonte

3 risposte

4

Quale classe dovrebbe sapere come convertire una nuova A in una legacy A ?

Forse è la classe A stessa che ha questa conoscenza. Può sapere come vengono mappati i nuovi valori legacy, quali campi devono essere aggiunti o rimossi, ecc. In questo caso il seguente approccio sembra del tutto naturale:

A legacyA = a.toLegacy();

Il vantaggio di questo approccio è la coerenza: è simile al metodo toString() che converte, ad esempio, un intero o un doppio in una stringa. La parte interessante qui è che mentre toString di int crea un'istanza di un tipo completamente diverso (stringa), toLegacy restituisce un'istanza dello stesso tipo.

Lo svantaggio è la violazione del principio SRP , nonché il fatto che il codice di conversione (in particolare per alcune forme legacy) sta inquinando la classe. Se la logica di conversione è complessa e ha poco a che fare con A stessa, ha senso spostare questo codice in una classe separata .

Questa situazione è molto simile al modello factory e pattern factory astratto: quando la logica richiesta per creare istanze di una classe diventa troppo complessa per rimanere nella classe stessa (in una forma di un metodo statico ), quindi viene utilizzato lo schema di fabbrica. Se ci sono molte entità simili, un modello astratto di fabbrica inizia ad essere prezioso.

In modo simile, puoi avere la classe del convertitore astratto e le classi concrete che trattano le conversioni di diverse entità di business :

abstract class ConverterToLegacy<T>
{
    public T Convert(T businessEntity);
}

class ConverterToLegacyA implements ConverterToLegacy<A>
{
    public A Convert(A a)
    {
        ...
    }
}

class ConverterToLegacyB implements ConverterToLegacy<B>
{
    public B Convert(B b)
    {
        ...
    }
}
    
risposta data 18.05.2015 - 14:55
fonte
1

Potresti avere una fabbrica che fornisce l'oggetto adatto corretto.

L'esposizione di una serie di classi o di una singola classe con più metodi presuppone che tu abbia una certa conoscenza prima della mano del sistema. Un altro (problematico, credo) problema è che esponendo tutti gli adattatori si sta dando al chiamante (client) il controllo completo su quale adattatore viene chiamato.

Questo, a mio parere, potrebbe causare alcuni problemi poiché qualcuno potrebbe cercare di trovare un modo (intenzionalmente per caso) attorno ad alcuni meccanismi interni che potresti avere (la convalida viene in mente) che potrebbe essere problematico.

Avere 1 endpoint che è esposto all'utente e che ha una logica che fa tutto ciò che ha bisogno di fare ti dà più controllo.

    
risposta data 18.05.2015 - 15:26
fonte
0

Sembra che tu stia chiedendo due cose diverse qui:

  1. changing the values of some fields

  2.   
  Ti stai riferendo a come hai bisogno di normalizzare le formattazioni dei valori ( "yyyy-MM-dd" in "ddMMyy" ) o forse anche i tipi di dati qui (% da% di conteggio a% diBigDecimal)? In tal caso, ti suggerisco di creare una classe di conversione per gestirli, in modo da poter eliminare in modo sicuro sia la conversione che gli errori API nella tua classe.

  1. making changes such that the new file complies to older schema

  2.   
  Wells, le librerie di serializzazione e il modo in cui gestiscono la risoluzione dello schema mi sono venute immediatamente in mente, come ad esempio come Apache Avro lo fa ... Se riesci a considerare i tuoi oggetti / file di dati (hmms un po 'troppo per questi ultimi) da gestire come una forma di serializzazione, allora queste librerie meritano sicuramente una visita qui, perché il problema è molto probabilmente risolto per te . Per il confronto completo sulla risoluzione dello schema, questo l'articolo è un ottimo, anche se un po 'travolgente, letto.

modifica Dato il rischio di link put, citerò solo le parti rilevanti dell'articolo qui ...

  1. Then you find that people are stuffing all sorts of random fields into their objects, using inconsistent types, and you’d quite like a schema and some documentation... hey, if you had a schema, you could avoid storing objects’ field names, and you could save some more bytes!

Once you get to the fourth stage, your options are typically Thrift, Protocol Buffers or Avro. All three provide efficient, cross-language serialization of data using a schema, and code generation for the Java folks.

In real life, data is always in flux. The moment you think you have finalised a schema, someone will come up with a use case that wasn’t anticipated, and wants to “just quickly add a field”. Fortunately Thrift, Protobuf and Avro all support schema evolution: you can change the schema, you can have producers and consumers with different versions of the schema at the same time, and it all continues to work. That is an extremely valuable feature when you’re dealing with a big production system, because it allows you to update different components of the system independently, at different times, without worrying about compatibility.

    
risposta data 19.05.2015 - 06:06
fonte

Leggi altre domande sui tag