brandonchinn178 / brandonchinn178.github.io

My personal website
https://brandonchinn178.github.io
0 stars 0 forks source link

The "Services" design pattern – Brandon Chinn #20

Open utterances-bot opened 1 year ago

utterances-bot commented 1 year ago

The "Services" design pattern – Brandon Chinn

Brandon Chinn's personal website

https://brandonchinn178.github.io/posts/2023/05/03/services-design-pattern

jespercockx commented 1 year ago

Perhaps I am missing something, but aren't "being parametric over the monad" and "passing an explicit record value with the services" two independent ideas? So if you want you could just make your service record parametric over the monad, and so have the best of both worlds (at the cost of some simplicity).

brandonchinn178 commented 1 year ago

@jespercockx Yeah, you certainly could parameterize the service record as UserService m. But this might be the worst of both worlds, as you'd have to include some constraints like MonadThrow m. Unless you'd want to include throwError in the service record, which would make this a feature not a bug.

Personally, I like plain IO because it's easier to explain ("you can do anything, we just have the convention of putting things into this record" vs "this function works for any monad m (dont worry about what a monad is) with these constraints"). Concrete types are easier to immediately understand than a polymorphic type with constraints (in general, not just for effects).

But I think devs should be empowered to mix and match design patterns to fit their needs.

giacomocavalieri commented 1 year ago

A pattern that comes to mind is the Hierarchical Free Monad, it reminds me of the service pattern in the sense that it forces you to carefully think about each subsystem’s interface. The only difference is that you can be more precise in avoiding to put IO everywhere but it can be quite harder to explain to a newcomer

etorreborre commented 1 year ago

I would like to mention https://github.com/etorreborre/registry for wiring lots of those services together when the implementation of one service requires other services so that eventually your whole app is a graph. Don't hesitate to ask questions if you want to follow this route!