lundi 20 février 2023

How can I design an abstract model for different implementations in Java

Currently, I'm using Json to send different data to different vendors, but I'm curious about if there is a better alternative to do it.

Let's see this way.

I have one library, to make some operations for different vendors.

Provider Library

class Google {
  String id;
  Integer amount;

  // getters and setters
}
class Oracle {
  String id;
  Integer amount;
  Instant request;

  // getters and setters
}
class AbstractRequest {
  String id;
  Integer amount;
  Instant request;

  // getters and setters
}
class ConverterGoogle<Google, AbstractRequest> {
  // convert between models
}

class ConverterOracle<Oracle, AbstractRequest> {
  // convert between models
}
interface Provider {
  void execute(AbstractRequest request);
  String key();
}
class GoogleProvider extends AbstractProvider {
  void execute(AbstractRequest request) {
    Google model = ConverterGoogle.convert(request);
    // operations with model
  }
  String key() { return "google"; }
}

class OracleProvider extends AbstractProvider {
  void execute(AbstractRequest request) {
    Oracle model = ConverterOracle.convert(request);
    // operations with model
  }
  String key() { return "oracle"; }
}

There is another Service project that uses the before library. Depending on specific runtime data, will determine which provider will be used.

Service Project

class OperationsService {
  void process(String data) { // data could be something like "google_ujk345678iju78fh4"
    Provider provider = providerService.getProvider(data);
    
    AbstractRequest request = requestCreatorService.create(provider.getKey(), data);

    provider.execute(request);
  }
}

class RequestCreatorService {
  AbstractRequest create(String providerKey, String data) {
    // retrieve information from database to create the proper AbstractRequest for each provider
  }
}

And well, what's the issue? If a new provider comes in, with a different model, the AbstractRequest only has 3 fields, then it should change to hold the new ones.

At this moment, I solved it by sending a JSON request and the provider library and each implementation is responsible to retrieve its necessary data. So, we do not depend on a generic/common abstract model, with specific fields.

interface Provider {
  void execute(String jsonRequest);
  String key();
}
class GoogleProvider extends AbstractProvider {
  void execute(String jsonRequest) {
    Google model = GoogleDataExtractor.convert(jsonRequest);
    // operations with model
  }
  String key() { return "google"; }
}

class OracleProvider extends AbstractProvider {
  void execute(String jsonRequest) {
    Oracle model = OracleDataExtractor.convert(jsonRequest);
    // operations with model
  }
  String key() { return "oracle"; }
}

Of course, I had to create a v2 of the library to not break current implementation and the service. It's in testing phase.

I would like to know if there is another way to do it, using other specific model data class, specific pattern, etc.

Aucun commentaire:

Enregistrer un commentaire