Mapping an Object Oriented Model on Clojure

Suppose we work in an object-oriented language and there are two classes X and Y, and there is a bi-directional relationship between these classes.

So instance X can point to instance Y and vice versa.

In Clojure, classes usually translate to maps, so we can have:

{:type :x :name "instance of X"} {:type :y :name "instance of Y"} 

How do we imagine a bi-directional relationship between these โ€œobjectsโ€ without using something like โ€œforeign keysโ€? Or is it usually what is directly transferred to the database?

+4
source share
1 answer

Quite often, there are deeply nested maps in Clojure that correspond to hierarchical trees of objects in object-oriented languages, for example,

 {:type :x :name "instance of X" :y {:type :y :name "instance of Y"}} 

In fact, it is so widespread that clojure.core provides basic functions such as get-in , assoc-in and update-in to make working with such structures easier.

Of course, this works best when there is a natural hierarchy or ownership relationship between the simulated objects. In the case of circular references, this structure breaks down (if you adhere to persistent data structures) - to understand why, try building a Clojure map that contains itself as a value.

The way I usually saw this is to introduce an indirect layer using atom :

 (def x {:type :x, :name "x instance", :y (atom nil)}) (def y {:type :y, :name "y instance", :x (atom nil)}) (set! *print-level* 3) ;; do this in the REPL to avoid stack overflow ;; when printing the results of the following calls (reset! (:yx) y) (reset! (:xy) x) 
+4
source

All Articles