简体   繁体   中英

How to build a custom intermediate operation pipeline in Java for a series of API calls?

I am working on a project which provides a list of operations to be done on an entity, and each operation is an API call to the backend. Let's say the entity is a file, and operations are convert, edit, copy. There are definitely easier ways of doing this, but I am interested in an approach which allows me to chain these operations, similar to intermediate operations in java Streams, and then when I hit a terminal operation, it decides which API call to execute, and performs any optimisation that might be needed. My API calls are dependent on the result of other operations. I was thinking of creating an interface

interface operation{

operation copy(Params ..);  //intermediate

operation convert(Params ..);  // intermediate

operation edit(Params ..); // intermediate

finalresult execute(); // terminal op

}

Now each of these functions might impact the other based on the sequence in which the pipeline is created. My high level approach would be to just save the operation name and params inside the individual implementation of operation methods and use that to decide and optimise anything I'd like in the execute method. I feel that is a bad practice since I am technically doing nothing inside the operation methods, and this feels more like a builder pattern, while not exactly being that. I'd like to know the thoughts on my approach. Is there a better design for building operation pipelines in java?

Apologies if the question appears vague, but I am basically looking for a way to build an operation pipeline in java, while getting my approach reviewed.

You should look at a pattern such as

EntityHandler.of(remoteApi, entity)
             .copy()
             .convert(...)
             .get();

public class EntityHandler {
    private final CurrentResult result = new CurrentResult();
    private final RemoteApi remoteApi;

    private EntityHandler(
          final RemoteApi remoteApi,
          final Entity entity) {
       this.remoteApi = remoteApi;
       this.result.setEntity(entity);
    }

    public EntityHandler copy() {
       this.result.setEntity(new Entity(entity)); // Copy constructor
       return this;
    }

    public EntityHandler convert(final EntityType type) {
       if (this.result.isErrored()) {
          throw new InvalidEntityException("...");
       }

       if (type == EntityType.PRIMARY) {
          this.result.setEntity(remoteApi.convertToSecondary(entity));
       } else {
          ...
       }

       return this:
    }

    public Entity get() {
       return result.getEntity();
    }

    public static EntityHandler of(
          final RemoteApi remoteApi, 
          final Entity entity) {
       return new EntityHandler(remoteApi, entity);
    }
}

The key is to maintain the state immutable, and handle thread-safety on localized places, such as in CurrentResult , in this case.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM