There are ways to handle dependencies without going down the OOP route that 
Stuart Sierra took. However, there are a lot of good ideas in Stuart 
Sierra's Component library, and to the extent that you can borrow those 
ideas, you end up with code that resembles "best practice" in the Clojure 
community. 

For me, one "Big Idea" that I got from Stuart Sierra is that there should 
be a "start" method that can be called either from the REPL or from -main 
(for when you app runs as a daemon). The other "Big Idea" I got was that 
there should be functions for handling the lifecycle of all the components 
in your app, so you can easily start and stop and restart. So nowadays my 
"core.clj" tends to look like this: 

(ns salesslick.core
  (:gen-class)
  (:require
   [salesslick.start :as start]
   [salesslick.stop :as stop]))

;; what you would call from the REPL to re-initate the app
(defn start []
  (try
    (start/start)
    (catch Exception e (println e))))

(defn stop []
  (try
    (stop/stop)
    (catch Exception e (println e))))

;; Enable command-line invocation
(defn -main [& args]
  (.addShutdownHook (Runtime/getRuntime)
    (Thread.
      #(do (println "Salesslick is shutting down")
        (stop))))
  (start))

So I can call "start" and "stop" from the REPL, or, if the app is running 
as a daemon, "start" gets called by -main, and "stop" is registered as a 
shutDownHook. 

These are great ideas that I got from Stuart Sierra, however, I did not 
feel the need to go as far toward OOP as Stuart Sierra did. And some of 
things he has suggested as "best practice" really strike me as odd. To be 
honest, some of the things he said were astonishing and went against 
everything I have learned over the years. I'm thinking of what he says in 
these 2 videos: 

http://www.infoq.com/presentations/Clojure-Large-scale-patterns-techniques

https://www.youtube.com/watch?v=13cmHf_kt-Q

At one point he says that "Object Oriented code has the advantage that it 
is obvious where you configure your code." 

Wow!!! What can I say about that!!! 

I have lost entire days because I was dragged into stupid, tedious meetings 
whose subject was "How should we refactor these fat Rails models?" 

I've been dragged into incredibly boring meetings to discuss Rails versus 
Sinatra, where the main thing under discussion was really the issue of 
configuration. 

When I am on my deathbed, looking back, I will recall some days fondly, and 
other days I will recall as wasted, and the most sadly wasted days of all 
are the days I was forced to discuss Dependency Injection with my 
co-workers. 

None of my experiences allow me to agree with Stuart Sierra that OOP makes 
it obvious how to configure an app. 

Still, without a doubt, there are good ideas in Stuart Sierra's Component 
library, and it is worth digging into them to find the good ideas. 

The place where I diverge from Stuart Sierra is in his use of Records. His 
main concern seems to be making dependencies visible. It's the same issue 
that Alex Miller focuses on here: 

http://tech.puredanger.com/2014/01/03/clojure-dependency-injection/

My own preference for making dependancies obvious is to use :pre 
assertions. I'm looking at Typed Clojure as a possibility for going further 
down that road. 

There might be use cases where it is fundamentally imperative to use 
something like Stuart Sierra's pseudo-OOP style, but I have not met those 
use cases yet. Most of the work I do tends to be the kind of thing where I 
can spin up some internal "workers" and have them pull work off a queue. I 
can initiate the workers from my "start" function and stop them with the 
"stop" function. Typically, each worker will have its own connection to 1 
or more databases, and each worker takes responsibility for closing its 
database connections once the "stop" function has been called. 

All of this is easy to do within the Functional Paradigm. 

I think there is a fascinating sociological question that haunts the 
Clojure community, regarding OOP. Many of the best Clojure developers spent 
10 or 20 years doing OOP before they came to Clojure, so how much do they 
bring OOP with them because they feel its natural, and they feel it natural 
because they spent so many years with the OOP style? 













On Wednesday, June 17, 2015 at 10:15:21 PM UTC-4, Xiangtao Zhou wrote:
>
> hi guys,
>
> Constructing simple clojure project is trival, just make functions. if the 
> project grows large, with more datasources, message queue, and other 
> storages, dependencies problem is on the table. 
>
> One solution is stuartsierra/component,  using system to configure 
> dependencies graph, make component and dependencies resolution separate.
>
> If we make namespace must run with code block that init the namespace, 
> like the "start" method in component, is this a good way to solve the 
> dependencies?
>
> because when the namespace is required the first time, the init block 
> worked once.
>
> any suggestion is appreciated.
>
>
> - Joe
>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
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 clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to