Fork me on GitHub
#architecture
<
2020-04-01
>
apbleonard16:04:30

@allaboutthatmace1789 By "onion-y" do you mean something like this? https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html ... I've often pondered the same - how to manage Clojure code so that inner code (doman layer) never "requires" outer code (resource layer). I thought the way to go might be multimethods ...

apbleonard16:04:45

This article seems to be even handed about the options, without being conclusive. (Sorry - I haven't fully read this!) http://blog.find-method.de/index.php?/archives/209-Dependency-inversion-in-Clojure.html Like the author here I really think most discussion of DI in clojure focuses on stateful resources and the startup cycle and not on dependency inversion which I think is lost in the noise, but which is very powerful for breaking up responsibilities in code.

Joe17:04:08

@apbleonard exactly - clean, onion, hexagonal, anything with that flavor. The article looks promising, thanks

apbleonard23:04:16

Went through the article - it appears to advocate protocols as the "premiere" approach I think. Protocols were also designed explicitly to help with the "expression problem" too, which otherwise bedevils attempts to build extensible APIs. It also dispatches on types, which as an OO developer used to using onion-y layers feels very temptingly familiar.... But on the other hand ... it dispatches on types 🙂 which pushes your layer APIs and design to express everything using types, which feels like a big price to pay. Not very data driven. I think that's why many guides tend to promote multimethods as the abstraction of choice over protocols (unless you care about speed) because of the flexibility of their dispatch by value. Again using multimethods in an onion-y way seems woefully under examined/documented. This old SO was the actual article I was looking for when I googled earlier and found the other Dependency Inversion article above, NB Look also at the very last comment, which seems to fix some people's gripes with the posted solution. Again - I'm afraid I haven't tried that code out myself! 🙂 https://stackoverflow.com/questions/39585510/using-clojure-multimethods-defined-across-multiple-namespaces

Joe19:04:07

That made a lot of sense! I tried to implement the same multimethod pattern with a repo flavour in line with my question and it worked at the REPL (though I didn't include the requires per the last SO comment - having the requires for the concrete implementations in the interface is a shame, but I guess not a big deal) https://github.com/RedPenguin101/Notes_Clojure/tree/master/dip_example

apbleonard22:04:34

Looks great! 🙂 In our workplace we use a form of "clean architecture" for all the Java services and it definitely helps tame some of the OO madness. But hardly use any "architectural patterns" at all in the Clojure services (other than using mount). And even though the Clojure language already helps in so many ways, the lack of internal structure/abstractions/layers in the logic does still lead to idiosyncratic and very tangled code sadly.

Joe19:04:07
replied to a thread:Went through the article - it appears to advocate protocols as the "premiere" approach I think. Protocols were also designed explicitly to help with the "expression problem" too, which otherwise bedevils attempts to build extensible APIs. It also dispatches on types, which as an OO developer used to using onion-y layers feels very temptingly familiar.... But on the other hand ... it dispatches on types :slightly_smiling_face: which pushes your layer APIs and design to express everything using types, which feels like a big price to pay. Not very data driven. I think that's why many guides tend to promote multimethods as the abstraction of choice over protocols (unless you care about speed) because of the flexibility of their dispatch by value. Again using multimethods in an onion-y way seems woefully under examined/documented. This old SO was the actual article I was looking for when I googled earlier and found the other Dependency Inversion article above, NB Look also at the very last comment, which seems to fix some people's gripes with the posted solution. Again - I'm afraid I haven't tried that code out myself! :slightly_smiling_face: https://stackoverflow.com/questions/39585510/using-clojure-multimethods-defined-across-multiple-namespaces

That made a lot of sense! I tried to implement the same multimethod pattern with a repo flavour in line with my question and it worked at the REPL (though I didn't include the requires per the last SO comment - having the requires for the concrete implementations in the interface is a shame, but I guess not a big deal) https://github.com/RedPenguin101/Notes_Clojure/tree/master/dip_example