Hello Clojure people,
First up, apologies because this is going to be a long message. Howver, if
you do have the time to read and respond, then I would be extremely
grateful!
Recently I've decided to give Clojure a proper go. Over the past year or so
I've paid it a bit of attention: I've read books all about how to use it
and I've spent a bit of time working through tutorials to create little web
apps and so on. I understand the language (although not to any great depth
yet), but I'm still unsure about the best approaches to actually working
with it.
I've got many years of OOP experience, and I'm a big fan of principles like
SOLID and approaches like DDD. What I want to do now is, try and learn how
to build well designed models using Clojure, while using best practices!
I've started having a bit of a crack at it by building a simple app, but
I'm finding myself trying to transfer a lot of my existing OOP techniques
into Clojure. It's working, but I'm wandering if I'm overdoing it or
perhaps just not doing things "the Clojure way".
So, my very first question is are there any good books or resources on
modelling, application architecture or best practices, using Clojure?
Next up, maps vs records. I've read that the typical approach is to use
maps until the design starts to solidify and then you can move to records.
Is the the general attitude of Clojure developers or do some like to dive
straight in with records?
The next question is encapsulation: I've taken the approach that I'm kind
of using namespaces like classes. If I want to create customer entity I
create a namespace for it, then add a "make" function to it which returns a
map of the right "shape". I'm then shying away from accessing the map
directly, and rather doing it through other methods in the namespace which
take the instance as a parameter. E.g.
(ns app.domain.customer)
(defn make [name, email]
{:name name
:email email})
(defn get-name [customer]
(:name customer))
Is this a reasonable approach? If not, what might be a better one?
This leads on to safety and defensive programming. Using the approach
above, how much "type safety" is required? Obviously, in any API which is
going to be used by other programmers, you've got to handle bad inputs
well. But what is the Clojure approach in the "domain model"? Coming from
the DDD mindset, where models are designed to be un-breakable, part of me
wants to use records for all entities and typehint for them everywhere.
However, I wander if the Clojure way is more about rigorous testing to make
sure the wrong values don't get put in in the first place? Also, what about
libraries like https://github.com/Prismatic/schema, this could be used in
:pre conditions to be more explicit, is that a common thing?
Next up, how far do you go with creating "types" vs using primitives?
Again, referring back to DDD, both the email and the name in the example
above are suitable candidates for value objects. In Clojure, would you
consider hiding the data behind a set of specialised functions to create,
access and use it? Or would you just pass the primitive
string/map/vector/whatever about and work on it directly? Example:
; Given
(defn make-customer [name email]
{:name name, :email email})
; Examples
(def customer1 (make-customer "Tom" "[email protected]"))
; vs...
(defn make-name [name] name)
(defn make-email [email] email)
(def customer2
(make-customer (make-name "Tom")
(make-email "[email protected]")))
I think that's all I want to ask about now. I do have other questions about
dependency inversions, but I'll leave that for another time. If you've read
this far then thank you very very much! Also,I know that no one really
wants to just sit and read though random peoples code, but, if you are
interested in my (very very early stages) experimental project, then I've
put in on https://github.com/tomphp/clojure-cocktails - any comments,
critiques, PRs or questions would be really great!
Thanks you so much for your times and I look forward to any thoughts or
suggestions!
Tom
--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to [email protected]
Note that posts from new members are moderated - please be patient with your
first post.
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
---
You received this message because you are subscribed to the Google Groups
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.