I have two classes of a one interface:
interface TimeUtils { ... }
class TimeUtilsImpl : TimeUtils { ... }
class TimeUtilsSimulation : TimeUtils { ... }
TimeUtils
binding is in the module A
:
bind(TimeUtils::class.java).to(TimeUtilsImpl::class.java).`in`(Singleton)
TimeUtilsSimulation
binding is in the module B
:
bind(TimeUtils::class.java).to(TimeUtilsSimulation::class.java).`in`(Singleton)
and these modules A
and B
are used in different binaries.
I injected TimeUtils
in a common code like:
class SomeClass @Inject constructor(
private val timeUtils: TimeUtils
)
And now I have a problem that when I have a request to start simulation I need to set an initial time in the TimeUtilsSimulation
object. I can do it like this:
class RequestHandler @Inject constructor(
private val someObject: SomeClass
)
onRequest(simulationStartTime: LocalDateTime) {
if (timeUtils instanceof TimeUtilsSimulation) {
// Set start time in a singleton timeUtils object
(timeUtils as TimeUtilsSimulation).setStartTime(simulationStartTime)
}
someObject.run()
}
but it looks ugly. Can you suggest something to solve this bad design?
CodePudding user response:
Maybe add setStartTime
to TimeUtils
interface and do not implement it in TimeUtilsImpl
? It all depends on the context. For unit testing for example I think your solution would be fine. But for other, "normal" business logic is seems fishy. It's almost like the interface does not really abstract the concept properly
CodePudding user response:
I don't know Kotlin, but pure OOP speaking, the best would be to define a TimeUtilsWrapper
interface that extends TimeUtils
and adds setStartTime(...)
method. Then you would have 2 classes implementing this interface:
- 1 that embeds a
TimeUtils
object with emptysetStartTime()
that delegates all other methods to the embedded object, - second that embeds a
TimeUtilsSimulation
and delegates all methods to it, includingsetStartTime()
calls to it.
Then SomeClass
method should have a property of type TimeUtilsWrapper
instead of TimeUtils
and onRequest(...)
should just always call TimeUtilsWrapper
's setStartTime(...)
.