移除在同步和异步实现之间共享的重复代码

huangapple 未分类评论44阅读模式
英文:

removing duplicate code shared between sync and async implementations

问题

给定一个 Processor 接口

public interface Processor {
    PBResponse process(PBEntity pbEntity);
}

我在我的框架项目中有两个实现一个是同步的

@Service("Synchronous")
public class SyncProcessor implements Processor {

    private final PBRepository pbRepository;
    private final JobRunner jobRunner;

    public SyncProcessor(PBRepository pbRepository, JobRunner jobRunner) {
        this.pbRepository = pbRepository;
        this.jobRunner = jobRunner;
    }

    @Override
    public PBResponse process(PBEntity pbEntity) {
       pbRepository.save(pbEntity);
       //其他业务逻辑和运行作业
        jobRunner.runJob(pbEntity);
    }
}

另一个是异步的

public class AsyncProcessor implements Processor {

    private final PBRepository pbRepository;
    private final JobRunner jobRunner;

    private ExecutorService executorService = Executors.newSingleThreadExecutor();

    public AsyncProcessor(PBRepository pbRepository, JobRunner jobRunner) {
        this.pbRepository = pbRepository;
        this.jobRunner = jobRunner;
    }

    @Override
    public PBResponse process(PBEntity pbEntity) {
        pbRepository.save(pbEntity);
        executorService.execute(new PBJobRunTask(pbRepository, jobRunner, pbEntity));
        return new PBResponse(...) //初始不完整的响应
    }

    private class PBJobRunTask implements Runnable {
        private final PBSFeedRepository pbsFeedRepository;
        private final JobRunner jobRunner;
        private final PBEntity pbEntity;

        public PBJobRunTask(PBRepository pbRepository, JobRunner jobRunner, PBEntity pbEntity) {
            //初始化
        }

        @Override
        public void run() {
            //其他业务逻辑和运行作业
            jobRunner.runJob(pbEntity);
        }
    }
}

在这两种同步和异步实现之间请求的处理是相同的唯一的区别是异步实现中使用了 ExecutorService 执行逻辑

处理逻辑在同步和异步实现中的 Runnable 的 run() 方法中重复

//重复的部分
pbRepository.save(pbEntity);
    //其他业务逻辑和运行作业
    jobRunner.runJob(pbEntity);

我需要一些帮助来去除这些重复的部分使得这两个实现可以共享我不确定是否将同步类注入到异步类中是否是一种良好的实践因为它们都是 Processor 的实现

什么是理想的也是一个良好的模式用于在这两个类之间共享业务逻辑我们还有存在于两个实现中的存储库和 JobRunner或许它们也可以被移动

提前感谢您的帮助
英文:

Given that I have an Processor interface:

public interface Processor {
    PBResponse process(PBEntity pbEntity);
}

And I have two implementation in my framework project, one synchronous:

@Service("Synchronous")
public class SyncProcessor implements Processor {

    private final PBRepository pbRepository;
    private final JobRunner jobRunner;

    public SyncProcessor(PBRepository pbRepository, JobRunner jobRunner) {
        this.pbRepository = pbRepository;
        this.jobRunner = jobRunner;
    }

    @Override
    public PBResponse process(PBEntity pbEntity) {
       pbRepository.save(pbEntity);
       //other business logic and run job
        jobRunner.runJob(pbEntity);
    }
}

The Other Async:

public class AsyncProcessor implements Processor {

    private final PBRepository pbRepository;
    private final JobRunner jobRunner;

    private ExecutorService executorService = Executors.newSingleThreadExecutor();

    public SyncProcessor(PBRepository pbRepository, JobRunner jobRunner) {
        this.pbRepository = pbRepository;
        this.jobRunner = jobRunner;
    }

    @Override
    public PBResponse process(PBEntity pbEntity) {
        pbRepository.save(pbEntity);
        executorService.execute(new PBJobRunTask(pbRepository, jobRunner, pbEntity));
        return new PBResponse(...) //initial incomplete Response
    }

    private class PBJobRunTask implements Runnable {
        private final PBSFeedRepository pbsFeedRepository;
        private final JobRunner jobRunner;
        private final PBEntity pbEntity;

        public PBJobRunTask(PBRepository pbRepository, JobRunner jobRunner, PBEntity pbEntity) {
            //initialise
        }

        @Override
        public void run() {
            //other business logic and run job
            jobRunner.runJob(pbEntity);
        }
    }
}

Processing of a request is identical between both sync and async implementations. The only difference is the logic is executed with an ExecutorService with async implementation.

The processing logic is repeated in both Synchronous and Asynchronous implementations within the Runnable run() method:

   //duplicated
   pbRepository.save(pbEntity);
        //other business logic and run job
        jobRunner.runJob(pbEntity);

I need some help remove this duplicated where both these implementation can share. I am not sure whether inject Synchronous class into Async in a good practice as they are both implementations of Processor.

What would be ideal and a good pattern to share the business logic between two classes. We have the repository and JobRunner which also sits in both implementations and perhaps they can move also?

Thanks in advance

答案1

得分: 0

你可以使用模板方法模式

定义一个抽象类AbstractProcessor并将Processor接口实现为final。在process(PBEntity pbEntity)方法中,将步骤定义为受保护的方法,带有默认或无实现,在子类中覆盖特定步骤。

public abstract class AbstractProcessor implements Processor {

  private final PBRepository pbRepository;
  private final JobRunner jobRunner;

  public AbstractProcessor(PBRepository pbRepository, JobRunner jobRunner) {
    this.pbRepository = pbRepository;
    this.jobRunner = jobRunner;
  }

  @Override
  public final PBResponse process(PBEntity pbEntity) {
    someBusinessLogic(pbEntity);
    execute(pbEntity);
    return new PBResponse();
  }

  protected void someBusinessLogic(PBEntity pbEntity) {
      pbRepository.save(pbEntity);
      //some other business logic
  }
  protected void execute(PBEntity pbEntity) {

  }

}

示例子类 -

@Service("Synchronous")
class SyncProcessor extends AbstractProcessor {

    public SyncProcessor(PBRepository pbRepository, JobRunner jobRunner) {
        super(pbRepository, jobRunner);
    }

    @Override
    protected void execute(PBEntity pbEntity) {
        getJobRunner().runJob(pbEntity);
    }
}
英文:

You can use template method pattern.

Define abstract class AbstractProcessor and implement Processor interface as final. In process(PBEntity pbEntity) define steps as protected method with default/no implementation and in child class override specific step

public abstract class AbstractProcessor implements Processor {

  private final PBRepository pbRepository;
  private final JobRunner jobRunner;

  public AbstractProcessor(PBRepository pbRepository, JobRunner jobRunner) {
    this.pbRepository = pbRepository;
    this.jobRunner = jobRunner;
  }

  @Override
  public final PBResponse process(PBEntity pbEntity) {
    someBusinessLogic(pbEntity);
    execute(pbEntity);
    return new PBResponse();
  }

  protected void someBusinessLogic(PBEntity pbEntity) {
      pbRepository.save(pbEntity);
      //some other business logic
  }
  protected void execute(PBEntity pbEntity) {

  }

}

Example child class -

@Service("Synchronous")
class SyncProcessor extends AbstractProcessor {

    public SyncProcessor(PBRepository pbRepository, JobRunner jobRunner) {
        super(pbRepository,jobRunner);
    }

    @Override
    public void execute(PBEntity pbEntity) {
        getJobRunner().runJob(pbEntity);

    }
}

huangapple
  • 本文由 发表于 2020年7月26日 02:56:25
  • 转载请务必保留本文链接:https://java.coder-hub.com/63092315.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定