3. DDD in Clojure - Amit Rathore @amitrathore
Saturday, 30 March 13
4. DDD in Clojure - Amit Rathore @amitrathore
OO can still teach us a thing or two
Saturday, 30 March 13
5. DDD in Clojure - Amit Rathore @amitrathore
In OO:
- nouns
- processes owned by nouns
- nouns are classes
- processes are methods
Saturday, 30 March 13
6. DDD in Clojure - Amit Rathore @amitrathore
In OO: In Clojure:
- nouns - verbs
- processes owned by nouns - domain model: functions that
- nouns are classes transform data
- processes are methods
Saturday, 30 March 13
7. DDD in Clojure - Amit Rathore @amitrathore
A few general guidelines for your domain:
- no side-effects
- no dependencies on external services
- validate outside the model boundary (validateur, bouncer, clj-
scheme)
- no illegal state in domain functions (slingshot)
Saturday, 30 March 13
8. DDD in Clojure - Amit Rathore @amitrathore
Namespace organisation at Zolo:
- main namespace called core (most projects do this)
- zolo.models.(user | contacts | …)
- zolo.gateway.(facebook | linkedin | twitter | …)
- zolo.utils.(calendar | strings | maps | …)
- zolo.api.*
- zolo.services.(user-service | …)
Saturday, 30 March 13
9. DDD in Clojure - Amit Rathore @amitrathore
When you have no idea:
- zolo.homeless.*
Saturday, 30 March 13
10. DDD in Clojure - Amit Rathore @amitrathore
Still relevant:
- SOLID principles
- Few public fns (lots of private, helper fns)
- small fns (3-4 lines)
- optimize for readability
Saturday, 30 March 13
21. Engines of Abstraction - Jim Duey
Ah, one more monads talk!
- Monoids in clojure - list, concat, set, union, hash-map...
- Functors - a context datatype and a fn (fmap) to apply a function to each
value inside that context
- Applicative Functors - a context datatype and two functions:
one that wraps a value in the context type 'amap' applies fns wrapped in
the context to parameters wrapped in the context
- Monads - context data type, fn that wraps values, fn (bind) to apply a fn
to wrapped values. The applied fn takes a value and returns a wrapped
value.
Saturday, 30 March 13
22. Engines of Abstraction - Jim Duey
Who wants a monads talk at #cljsyd? :)
Saturday, 30 March 13
23. Clojure in the Large - Stuart sierra
Saturday, 30 March 13
24. Clojure in the Large - Stuart sierra
Lisp is a ball of mud
- not a lot of structure: namespaces and vars. That’s it.
- namespaces: not first-class modules
- def and defn are global by default
Also talked about encapsulation and global state
Saturday, 30 March 13
25. Clojure in the Large - Stuart sierra
Encapsulation anti-pattern:
;; Tempation to share it promiscuously!
(def state-a (ref {}))
;; Hidden dependencies
(defn op1 []
(dosync
(alter state-a ...)))
Saturday, 30 March 13
26. Clojure in the Large - Stuart sierra
Encapsulation: use local-state instead
;; Well-defined initial state. 'Go together' semantics
(defn constructor []
{:a (ref {})
:b (atom 0)})
;; Makes function dependencies clear
(defn op1 [state]
(dosync
(alter (:a state) ...)))
Saturday, 30 March 13
27. Clojure in the Large - Stuart sierra
with-* macros:
- assumes body starts and ends in a single thread
- assumes doesn’t return lazy seqs
- limits caller to one resource at a time
Saturday, 30 March 13
28. Clojure in the Large - Stuart sierra
Anti-pattern - thread-bound state:
(def ^:dynamic *resource*)
(defn- internal-op1 []
... *resource* ...)
;;another hidden dependency
(defn op1 [arg]
(internal-op1 ...))
Saturday, 30 March 13
29. Clojure in the Large - Stuart sierra
Local state with dynamic extent: nested with-resources
;; Pass around "context" argument
(defn op1 [context] ;; not confined to a single thread
;; acquire resources
(let [resource (::resource context)]
;; use namespace qualified keys
(assoc context ::result1 ...)))
;; still need to manage resource lifecycle
(defn finish [context]
(update-in context [::resource] dispose))
Saturday, 30 March 13
30. Clojure in the Large - Stuart sierra
When is it safe to use global Vars?
- True constants: (def ^:const gravity 6....)
- True singletons: (def runtime (Runtime/getRuntime))
- For REPL dev
- Private dynamic vars are OK:
(def ^:private ^:dynamic *state*)
(binding [*state* ....]
...)
Saturday, 30 March 13
31. Pedestal
No point in showing it here. Go to http://pedestal.io/
Saturday, 30 March 13
33. Beyond contracts - Paul deGrandis
core.specs: automatically generate tests and
documentation and contracts from REPL explorations:
https://github.com/ohpauleez/sterling
Saturday, 30 March 13
36. PuppetDB - centralised DB for Puppet developed in
Clojure
Why Clojure?
- Issues with Ruby: slow, GIL, garbage collection
Puppet DB is a layer on top of PostgreSQL
Write pipeline:
- async, parallel, MQ-based, automatic retry
Read pipeline:
- DLS, AST-based, transferred over the wire using JSON
- you can write your own
Saturday, 30 March 13
37. Securing Clojure Web Apps/Services with Friend -
Chas Emerick
Saturday, 30 March 13
38. Securing Clojure Web Apps/Services with Friend -
Chas Emerick
- Authentication and Authorization library for Clojure
- Ring middleware
Saturday, 30 March 13
39. Securing Clojure Web Apps/Services with Friend -
Chas Emerick
Batteries included:
- Authentication workflows
- form-based "interactive" login
- HTTP basic (Digest, soon)
- OpenId (Google, Yahoo, Wordpress etc...)
- "Channel enforcement" (e.g. require HTTPS)
- Authorization Options
- Roles based on Clojure's ad-hoc hierarchies
- functions, macros, and ring middleware for enforcinf role-based
auth policy
- Arbitrary imperative control
Saturday, 30 March 13
40. Securing Clojure Web Apps/Services with Friend -
Chas Emerick
https://github.com/cemerick/friend
Saturday, 30 March 13
42. pallet.clj - Infrastructure project file
pallet-lein plugin: https://github.com/pallet/pallet-lein
create pallet.clj file
> lein pallet up <-- local
or on EC2...
Saturday, 30 March 13
43. clj-v8 and the dieter asset pipeline
Saturday, 30 March 13
44. clj-v8 and the dieter asset pipeline
JS/CSS minification, concatenation and cache busting:
https://github.com/edgecase/dieter
Saturday, 30 March 13
48. Macros vs. Monads
Synthread: https://github.com/LonoCloud/synthread
- Presented as an alternative do the state monad:
(require '[synthread :as ->])
(-> {}
f1
f2
f3)
Saturday, 30 March 13
49. Macros vs. Monads
And it’s got lots of other useful macros:
->/do
->/if
->/when
->/for
->/assoc
->/update-in
Saturday, 30 March 13
50. The End
Questions?
Leonardo Borges
@leonardo_borges
http://www.leonardoborges.com
http://www.thoughtworks.com
Saturday, 30 March 13