I wish to know what is the idiomatic way to achieve data encapsulation in Clojure. Below I describe my particular use case to motivate the example code I provide.
I have code in a dbaccess module that performs a complex database query to fetch some data from a database. I also have a number of functions that operate on the returned, raw, data. These functions then provide more processed, refined views of the data and are invoked numerous times with different arguments from other modules in the system. Let's call them "API functions".
The query is heavy and should execute only once at the beginning, the API functions will then operate on the raw-data from memory without having to perform another DB query.
Here's my approach using closures:
(ns dbaccess)
(let
[raw-data (complex-database-query)]
(defn create-client-names []
(fn [some-args] raw-data))
(defn create-client-portfolio []
(fn [some-args] raw-data))
(defn create-client-stocks []
(fn [some-args] raw-data)))
(def client-names (create-client-names))
(doall (map println (client-names "Baltimore")))
I dislike having to name the created functions that have captured the raw-data.
More importantly, the code above doesn't allow the client modules to configure aspects of the query before it executes (e.g. the database connection information).
If, on the other hand, closures are not used I will have to explicitly pass the raw-data back and forth between the dbaccess module and the other modules that need to invoke API functions. Is there a better way? Should I perhaps use mutable state in the dbaccess module?
I will have to explicitly pass the raw-data back and forth between the dbaccess module and the other modules that need to invoke API functions
You should do this, pass the data the function need explicitly, because:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With