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.