debasishg / frdomain

Code repo for Functional and Reactive Domain Modeling
Apache License 2.0
467 stars 136 forks source link

Chapter 6: Introduce future at the repository level #40

Open arinal opened 7 years ago

arinal commented 7 years ago

The root cause why the operation need to return Future is because repository. Rather than eagerly calling Future.apply in service level, why can't we introduce Future as the return type from repository, and compose it accordingly in service level?

Let's say our repository is non-blocking, we will call this already well-shaped repository in another thread, which is unnecessary.

debasishg commented 7 years ago

That's definitely an option - no design is ever complete and there are always alternatives. In fact instead of committing to Future in the repository you can make it return a Monad (in the style of tagless final), which can be specialized to Future for your implementation. The advantage is that testing becomes easier - you can test your repository using the Identity monad, while continue to use Future in production implementation.

arinal commented 7 years ago

At one perspective people would say returning generic Monad will blur the original intention of the function definition, another perspective would say repository doesn't have to return Future as InMemoryRepository usually do. Apart from it, I can see elegance in this and want to using it in my projects, do you ever use it in production?

Somehow I still prefer using Future as it will be more understandable for beginner readers, and using Future.successfull with fake ExecutionContext as a replacement for returning Identity monad. Remember, your reader haven't yet introduced to Identity monad :)

NB: Those beginner readers remind me of myself several months ago. Thanks to your book!

debasishg commented 7 years ago

Using Future is ok functionally and may suit the beginner as well. I am a huge fan of parametricity and generally prefer to use concrete types at the boundary. Hence the suggestion for Monad. The problem with concretizing with Future is that in unit tests u still need all the machinery of Future that u also have mentioned even to use a Map as the repository. Anyway, it's better to start simple :-)