Scala - 为工厂实例化的子类提供不同的依赖项



我正在尝试编写一个作业执行模块,该模块使用工厂来提供执行作业的逻辑,具体取决于作业的类型。

我遇到的困境是如何为特定实现提供不同的依赖项,同时保留通用签名以进行实例化。

删节代码如下。

带工厂的基类:

abstract class JobExecution(job: Job, jobService: JobService) {
    def execute: Unit
}
object JobExecution {
  val registry: Map[Long, (Job, JobService) => JobExecution] = Map(
    1L -> ((j: Job, s: JobService) =>
      new SomeJobExecImpl(j, s).asInstanceOf[JobExecution])
  )
  def apply(job: Job, service: JobService): JobExecution = registry(job.jobTypeId)(job, service)
}

传入作业以这种方式执行:

// Note that here I have the services in scope that I would like to supply to the job execution implementation.
JobExecution(someJob, jobService).execute

我需要像这样实现:

class SomeJobExecImpl(job: Job, jobService: JobService, otherService: OtherService)
  extends JobExecution(job, jobService) {
    def execute: Unit = ???
}

或者也许:

class SomeJobExecImpl(job: Job, jobService: JobService)
                     (implicit otherService: OtherService)
  extends JobExecution(job, jobService) {
    def execute: Unit = ???
}

除了一些臭味的解决方法之外,我无法设计出解决方案。

是否有令人信服的方法可以在保留基本模式的同时做到这一点,还是需要大规模更改?

请注意,我没有使用 DI 库。

只需对现有结构进行最少的更改,一种选择是在ServiceRegistry中列出所有服务,如下所示:

trait ServiceRegistry {
  implicit val jobService: JobService
  implicit val otherService: OtherService
  ...
}

然后更改JobExecution注册表:

...
object JobExecution {
  val registry: Map[Long, (Job, ServiceRegistry) => JobExecution] = Map(
    1L -> ((j: Job, r: ServiceRegistry) =>
      import r._
      new SomeJobExecImpl(j, r.jobService).asInstanceOf[JobExecution])
  )
  def apply(job: Job, serviceReg: ServiceRegistry): JobExecution = 
    registry(job.jobTypeId)(job, serviceReg)
}

JobExecution实施需要其他服务时:

class SomeJobExecImpl(job: Job, jobService: JobService)
                     (implicit otherService: OtherService)
  extends JobExecution(job, jobService) {
    def execute: Unit = ???
}

最新更新