I'm new in scala programming. I'm puzzled now for how to declare a biz method in a asynchronous and functional way, that the method implementation should include many log message. As a bad practice, I write the code like this :
// trait
trait StoreService {
def create[Config]: Kleisli[Future, Config, Store]
}
// and the interpreter
trait StoreServiceInterpreter extends StoreService {
def create[Config]: Kleisli[Future, Config, Store] = Kleisli {cfg =>
// some implementation ...
log.info("bla bla bla ...")
// some implementation ...
// return a store
Store(...)
}
}
It's bad, cause the implementation is with side-effect, log something int the place. So, I change the method declaration like this:
// trait
trait StoreService {
def create[Config]: Kleisli[Future, Config, Writer[Vector[String], Store]]
}
// and the interpreter
trait StoreServiceInterpreter extends StoreService {
def create[Config]: Kleisli[Future, Config, Writer[Vector[String], Store]] = Kleisli {cfg =>
// some implementation ...
// log.info("bla bla bla ...")
// some implementation ...
// return a store
Writer(Vector("bla bla bla...", Store(...))
}
}
Using the Writer, the side-effect is eliminated, but the code is not clear:
- Why a writer returned?
Writer[Vector[String], Store]
has more noises thanStore
, has any way to avoid the boilerplate code and remain the no-side-effect? - Write
log
is not ad-hoc! I should build a vector of String to hold the message, using:+
or++
operation to add log. I think it's not ad-hoc logging, just like writelog.info(...)
anywhere.