On 29 July 2015 at 01:07, zcaudate <z...@caudate.me> wrote: > The example in the article is probably the smallest example I can come up > with. > > http://z.caudate.me/the-abstract-container-pattern > > The code for the concrete implementations speaks for itself I think, it is > about 10 lines to hook in jetty and http-kit to the framework. >
I'm afraid I don't see the benefit of having two tiers of abstraction in your example. I think you could achieve the same result with a simpler architecture. For example, consider a protocol: (defprotocol Lifecycle (-start [service]) (-stop [service])) We can add additional functionality around this simply by wrapping the protocol methods with functions: (defn start [service] (if (:started? service) service (-> service -start (assoc :started? true)))) (defn stop [service] (if-not (:started? service) service (-> service -stop (dissoc :started?)))) So in this case we're adding idempotence and a key to determine whether or not the service has been started. We assume that a service is a record that implements Lifecycle. We could also conceive of a function that globally registers services for convenience: (def running-services (atom #{})) (defn register! [service] (swap! running-services conj service)) (defn deregister! [service] (swap! running-services disj service)) Then work that into the start and stop functions: (defn start [service] (if (:started? service) service (-> service -start (assoc :started? true) (doto register!)))) (defn stop [service] (if-not (:started? service) service (-> service (doto deregister!) -stop (dissoc :started?)))) Now, if we actually want to create a service for an adapter like Jetty: (defrecord JettyService [handler options] Lifecycle (-start [service] (assoc service :instance (run-jetty handler (assoc options :join? false))) (-stop [service] (.stop (:instance service)) (dissoc service :instance))) Unless I've missed something, that seems like broadly equivalent functionality, but with arguably less complexity. We stick with functions for the most part, and only use polymorphism where it's necessary. - James -- 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.