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
TimeUtilsobject with emptysetStartTime()that delegates all other methods to the embedded object, - second that embeds a
TimeUtilsSimulationand 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(...).
