Hi, 2010/12/1 Michael Ossareh <ossa...@gmail.com>
> Hi All, > > In the course of putting together my latest piece of work I decided to > really embrace TDD. This is run of the mill for me in Java: > > - create some object that models your flow > - create some object which contains your storage logic > - create tests > - dependency inject the correct storage logic depending on which scenario > you're running in (prod / test / etc). > > Hum, this process does not seem to be eligible to be named "TDD". In TDD, the tests are written first and "shape" the interface of your solution. Here what to do is more "traditional": you write your domain objects, your logic, and you add tests. Not a critic of the methodology (I'm not advocating any methodology over another here, to be clear), but rather a thought on how things are named. Some more thoughts (not sure they will help, but who knows ?) : > I've not been able to think about how to correctly achieve this same > functionality in clojure. > > So far everything is pretty much pure functions, the storage functions > being the only place where data is changed. Currently the storage is > implemented with atomic maps. The production storage will be in Riak. > Hmm, if by "storage functions being the only place where data is changed" you mean that in storage functions you do 2 things: change the value and store them, then IMHO you could split them in 2. > I'm getting ready to build the Riak backend and now I'm faced with how to > choose the correct backing implementation. I've a namespace, > rah.test-storage, which implements the in-memory storage and I anticipate > putting riak storage in rah.riak-storage - however I'm not sure what the > best way to select the correct implementation at runtime or test time is. > > One solution I've come up with is to use defprotocol to define the > functions for the storage layer (as you would an interface in java) and then > have a defrecord for each implementation. Assume these to be in the > namespace rah.storage, which would also house the functions which call the > correct defrecord functions based on a property given at start time. > > This solution, however, feels like me trying to write Java in clojure - and > I'm wondering how the lispers of the world would solve this same issue. > > Another solution would be to write the same set of functions in the > rah.storage namespace which then look at the same property and then decide > whether to call rah.riak-storage/store-user! or > rah.test-storage/store-user!. > The solution, as every solution, will have to be a trade-of. Here one "axis" for the tradeoff can be seen as "how powerful you want your backend connectivity to be (singleton backend per app ? possibly several different backends at the same time ? pluggable backends during runtime ?) versus the ease of writing the app (the more probability you want power, the more probability there will be to have a "backend" object to be passed around : no backend object in case of a singleton backend for the app, several singleton backend objects). Note that if you know that each singleton backend will be of a "different kind" than the others, then simply a keyword for representing each backend may be sufficient. >From what I can infer from what you described, if you would write the application without caring about programmatic testing, you would be fine by just having top level functions, and probably a top level configuration map with key/values for backend location, credentials, etc. If so, then it may be sufficient to leverage the possibility, in your testing "framework" (clojure.test ? anything else ...) to redefine the functions of the backend before the tests run. I'm pretty sure there are already such features allowing to temporarily "redef" (and "restore" at the end) the root value of global vars. HTH, -- Laurent -- 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