Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Clojure Architecture like Uncle Bob did

I am trying to implement Clojure architecture like Uncle Bob did there http://blog.8thlight.com/uncle-bob/2012/08/13/the-clean-architecture.html and like he describe in clean code in Episode 07 - Architecture, Use Cases and High Level Design.

Nothing in an inner circle can know anything at all about something in an outer circle.

enter image description hereenter image description here

I want to code core of app with all business rules and tests. This core has to have definitions of operations on "objects" in database like user, payment, advertisement etc. But the implementation of how this should be done has to be on higher level of application.

So the question is: can you give me an example of good architecture application on github like on image with circles? I am learning Clojure and I want to see how technically it can be done. I am trying to do it myself but I have bad results. Simple example of code will help me a lot. I want to know how create layers in Clojure like on image step by step.

I will be glad for any information on how to do that with high quality in Clojure. Can be code, video or article. Can be free or can buy.

like image 761
kabra Avatar asked Apr 25 '15 16:04

kabra


1 Answers

The key element for Uncle Bob's clean architecture is dependency inversion. There are multiple ways to implement this with Clojure: using higher order functions and protocols are probably the two most relevant (shameless plug for a blog post of mine on dependency inversion in Clojure). E.g., you could define a persistence protocol for your data, which is completely ignorant of the particular implementation:

 (defprotocol MyDataDao
    (load-data [])
    (save-data []))

You could then have an implementation of said protocol which could use the database or the normal file system (note: the use of reify is only one option):

 (defn make-mydata-db-dao []
    [... db-setup-code ... ]
    (reify MyDataDao
         (load-data []
            [... data-query-code ...])
         (save-data []
            [... data-save-code ...])))

Instead of the hand-crafted make-mydata-db-dao you might want to look at Stuart Sierra's excellent component library.

However, you also need to implement the different circles: that's basically a question of using namespaces and ensuring that you put e.g. protocol definitions into the right inner circles/layers and the implementations into the correct outer layer.

Let's assume your gateway code is in general in the namespace app.gateway.*. Then the protocol MydataDao might end up in the namespace app.gateway.dao. The implementation though would belong in a different, outer circle. Let's say all your db code is in the namespace app.db.*, then you might put make-mydata-db-dao into app.db.dao.

Unfortunately, I don't know of any existing codebase in Clojure which implements this thoroughly. Actually, I would be interested in seeing a real-world example of this implemented in any language and hearing more about the benefits and downsides or difficulties of using it.

like image 186
schaueho Avatar answered Sep 18 '22 01:09

schaueho