Error in user YAML: (<unknown>): mapping values are not allowed in this context at line 1 column 26
---
title: Clean Architecture: Kotlin Use Cases
---
Use Cases can be both asynchronous and synchronous.
The primary difference is that a synchronous Use Case will return it's result, and an asynchronous Use Case will call a callback with it's result.
It is possible to generalise the boundary interfaces of these two types of Use Cases.
Asynchronous use cases provide greater control over rendering to the UI. However they add complexities to testing.
An example generalisation can be found here, with a derivative here for a specific use case.
package com.acmeindustries.widget.usecase
interface ViewWidgets {
fun execute(request: Request, presenter: Presenter)
data class Request(...)
interface Presenter {
fun onSuccess()
fun onError()
}
}
Synchronous Use Cases provide a simpler interface for testing, but can make representing failure paths and control over the UI harder to maintain.
package com.acmeindustries.widget.usecase
interface ViewWidgetPerFooBarReport {
fun execute(request: Request): Response
data class Request(public val fromDate: String, public val endDate: String)
data class Response(...)
}
package com.acmeindustries.widget
import com.acmeindustries.widget.usecase.ViewWidgetPerFooBarReport
import com.acmeindustries.widget.usecase.ViewWidgetPerFooBarReport.*
import com.acmeindustries.widget.domain.Widget
class WidgetPerFooBarReport(val widgetGateway: WidgetGateway) : ViewWidgetPerFooBarReport {
fun execute(request: Request): Response {
val widgets = widgetGateway.all()
//secret sauce here
return Response(...) //return response populated with data
}
}
interface WidgetGateway {
fun all(): List<Widget>
}