随着 Arrow 1.1.x 的到来,我们获得了新的Effect类。
到目前为止,我的业务类返回 Either 来模拟返回错误或值的效果,例如:
@Service
class CreateDepartmentUseCaseImpl(
private val createDepartmentsDrivenPort: CreateDepartmentsDrivenPort,
private val getDepartmentByCodeDrivenPort: GetDepartmentByCodeDrivenPort
) : CreateDepartmentUseCase {
override suspend fun execute(param: Department): Either<DomainError, Department> =
Either.conditionally(getDepartmentByCodeDrivenPort.get(param.code) == null,
{ DepartmentAlreadyExistsError(param.code.value) },
{ createDepartmentsDrivenPort.create(param) })
}
Run Code Online (Sandbox Code Playgroud)
在新版本中Effect,这可以重构为:
@Service
class CreateDepartmentUseCaseImpl(
private val createDepartmentsDrivenPort: CreateDepartmentsDrivenPort,
private val getDepartmentByCodeDrivenPort: GetDepartmentByCodeDrivenPort
) : CreateDepartmentUseCase {
override suspend fun execute(param: Department): Effect<DomainError, Department> = effect {
ensure(getDepartmentByCodeDrivenPort.get(param.code) == null) { DepartmentAlreadyExistsError(param.code.value) }
createDepartmentsDrivenPort.create(param)
}
}
Run Code Online (Sandbox Code Playgroud)
在测试中,模拟更改为:
@Test
fun `should create department`() = runTest {
val dep = createValidDepartment()
val createDepartmentRequest = CreateDepartmentRequest(dep.code.value, dep.name.value, dep.description.value)
`when`(createDepartmentsUseCase.execute(dep)).thenReturn(dep.right())
Run Code Online (Sandbox Code Playgroud)
到...
@Test
fun `should create department`() = runTest {
val dep: Department = createValidDepartment()
val createDepartmentRequest = CreateDepartmentRequest(dep.code.value, dep.name.value, dep.description.value)
`when`(createDepartmentsUseCase.execute(dep)).thenReturn(effect { dep })
Run Code Online (Sandbox Code Playgroud)
问题是,对我们的业务服务(新Effect类 或 )进行建模的最佳方法是什么Either?为什么?
nom*_*Rev 10
没有理由重构Effect是否Either适合您的用例。
问题是,对我们的业务服务进行建模的最佳方法是什么,是新的 Effect 类还是 Either,为什么?
遗憾的是,就像在软件中一样,没有一劳永逸的答案,但我通常会推荐对业务服务进行建模Either。
Effect<E, A>在语义上等价于suspend EffectScope<E>.() -> A,并且运行该 lambda 的结果可以是Either<E, A>。
这也是为什么我们可以分配Effect给 a val,并且在返回时Either我们需要调用需要 的 suspend lambda suspend fun。
val operation: Effect<E, A> =
effect { ... }
suspend fun operation(): Either<E, A> =
operation.toEither()
Run Code Online (Sandbox Code Playgroud)
因此,如果您只需要对操作结果Either<E, A>进行建模,那么就需要使用。如果您需要传递 lambda/操作,则Effect可以使用 using 。
您可以考虑Effect比 更低级别的实现Either,因为所有计算块(例如either { }、option { }、ior { }、result { }等)现在都通过 实现effect。
您可以在 的 Arrow 实现中看到这一点either { }。
suspend fun <E, A> either(block: suspend EffectScope<E>.() -> A): Either<E, A> =
effect(block).toEither()
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
743 次 |
| 最近记录: |