Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Dependency management in Clojure

schaueho
February 20, 2016

Dependency management in Clojure

Dependencies between components are one of the primary drivers of the flexibility of any bigger applications. Clojure provides a number of tools to manage dependencies, some are built-in, some are built on libraries. We’ll look at basic building blocks like higher-order functions and protocols, but also at libraries like Stuart Sierra’s component.

Presentation by Holger Schauer at ClojureD, Berlin, 2016-02-20

schaueho

February 20, 2016
Tweet

More Decks by schaueho

Other Decks in Programming

Transcript

  1. (ns playitloud.ui-player (:require [playitloud.simple-player :refer [play]])) (defn play-pressed [randomize] (println

    "User pressed play") (play randomize)) (ns playitloud.simple-player (:require [playitloud.speaker :refer [blare]] [playitloud.musiccoll :refer [get-songs]])) (defn play [randomize] (let [songs (get-songs) songs (if randomize (shuffle songs) songs)] (map (fn [song] (blare song)) songs)))
  2. (ns playitloud.ui-player (:require [playitloud.simple-player :refer [play]])) (defn play-pressed [randomize] (println

    "User pressed play") (play randomize)) (ns playitloud.simple-player (:require [playitloud.speaker :refer [blare]] [playitloud.musiccoll :refer [get-songs]])) (defn play [randomize] (let [songs (get-songs) songs (if randomize (shuffle songs) songs)] (map (fn [song] (blare song)) songs))) (ns playitloud.speaker) (defn blare [song] (let [result (str "Speaker plays " song)] (println result) result))
  3. (ns playitloud.ho.player) (defn play [blarefn songgetterfn randomize] (let [songs (songgetterfn)

    songs (if randomize (shuffle songs) songs)] (map (fn [song] (blarefn song)) songs)))
  4. (ns playitloud.ho.player) (defn play [blarefn songgetterfn randomize] (let [songs (songgetterfn)

    songs (if randomize (shuffle songs) songs)] (map (fn [song] (blarefn song)) songs))) ; --------------------------------------------------- (ns playitloud.ho.ui-player (:require [playitloud.ho.player :as ho :refer [play]] [playitloud.speaker :as speaker] [playitloud.headphone :as headphone] [playitloud.blue-streamer :as streamer] [playitloud.musiccoll :refer [get-songs]])) (defn play-pressed [speaker randomize] (println "User pressed play") (condp = speaker :speaker (play speaker/blare get-songs randomize) :headphone (play headphone/blare get-songs randomize) :stream (play streamer/blare get-songs randomize)))
  5. (defn make-playfn "Returns a function that will play all songs"

    [blarefn songgetterfn] (fn ; Plays all songs, potentially randomized [randomize] (let [songs (songgetterfn) songs (if randomize (shuffle songs) songs)] (map (fn [song] (blarefn song)) songs))))
  6. (ns playitloud.ho.play-config [...] (def speaker-play (make-playfn speaker/blare get-songs)) (def headphone-play

    (make-playfn headphone/blare get-songs)) (def stream-play (make-playfn streamer/blare get-songs)) (defn select-playfn [speaker] (condp = speaker :speaker speaker-play :headphone headphone-play :stream stream-play)) (ns playitloud.ho.clos-ui-player (:require [playitloud.ho.play-config :refer [select-playfn]])) (defn play-pressed [output randomize] (let [playfn (select-playfn output)] (playfn randomize)))
  7. (ns playitloud.services.config) (def ^:dynamic *services* {:blare playitloud.speaker/blare :get-songs playitloud.musiccoll/get-songs}) (ns

    playitloud.services.player (:require [playitloud.services.config :refer [*services*]])) (defn- blare [sound] ((:blare *services*) sound)) (defn- get-songs [] ((:get-songs *services*)))
  8. (ns playitloud.services.config) (def ^:dynamic *services* {:blare playitloud.speaker/blare :get-songs playitloud.musiccoll/get-songs}) (ns

    playitloud.services.player (:require [playitloud.services.config :refer [*services*]])) (defn- blare [sound] ((:blare *services*) sound)) (defn- get-songs [] ((:get-songs *services*))) (defn play [randomize] (let [songs (get-songs) songs (if randomize (shuffle songs) songs)] (map (fn [song] (blare song)) songs)))
  9. (ns playitloud.sig.output-device (:require [de.find-method.funsig :refer [defsig]])) (defsig blare "Play sound

    loudly!" [sound]) (ns playitloud.sig.speaker (:require [de.find-method.funsig :refer [defimpl]] [playitloud.sig.output-device :refer [blare]])) (defimpl blare [sound] (let [result (str "Speaker plays " sound)] (println result) result))
  10. (ns playitloud.sig.output-device (:require [de.find-method.funsig :refer [defsig]])) (defsig blare "Play sound

    loudly!" [sound]) (ns playitloud.sig.speaker (:require [de.find-method.funsig :refer [defimpl]] [playitloud.sig.output-device :refer [blare]])) (defimpl blare [sound] (let [result (str "Speaker plays " sound)] (println result) result)) (ns playitloud.sig.player (:require [playitloud.sig.output-device :refer [blare]] [playitloud.musiccoll :as mc :refer [get-songs]])) (defn play [randomize] (let [songs (get-songs) songs (if randomize (shuffle songs) songs)] (map (fn [song] (blare song)) songs)))
  11. (ns playitloud.proto.output-device) (defprotocol OutputDevice (blare [device sound]) (inc-volume [device]) (dec-volume

    [device])) (ns playitloud.proto.speaker (:require [playitloud.proto.output-device :as output :refer :all])) (defrecord Speaker [volume] OutputDevice (blare [_ sound] (let [result (str "Speaker plays " sound)] (println result) result)) ;[...]
  12. (ns playitloud.proto.player (:require [playitloud.proto.output-device :as output] [playitloud.musiccoll :as mc])) (defn

    play [output-device randomize] (let [songs (mc/get-songs) songs (if randomize (shuffle songs) songs)] (map (fn [song] (output/blare output-device song)) songs)))
  13. (ns playitloud.comp.streamer (:require [com.stuartsierra.component :as component] [playitloud.comp.output-device :as output :refer

    :all] [playitloud.comp.remote-connection :as remote])) (defrecord BlueStreamer [connection volume] OutputDevice (blare [streamer sound] ;... normal protocol/record implementation ...) component/Lifecycle (start [streamer] (println "BlueStreamer starting") (connect (:connection streamer) streamer) (assoc streamer :status :connected)) (stop [streamer] (println "BlueStreamer stopping") (disconnect (:connection streamer) streamer) (->> (assoc streamer :status :disconnected) (dissoc :connection)))) (defn new-blue-streamer [config] (->BlueStreamer nil (:default-volume config)))
  14. (ns playitloud.comp.config (:require [com.stuartsierra.component :as component] [playitloud.comp.blue-connection :as blueconn] [playitloud.comp.streamer

    :as streamer] [playitloud.comp.player :as player])) (def default-config {:bt-conn {:name "Fabuluous-Connectivity" :port "1234"} :default-volume 5}) (defn make-player-system "Setup the player system" ([] (make-player-system default-config)) ([config] (component/system-map :connection (blueconn/new-connection config) :output-device (component/using (streamer/new-blue-streamer config) [:connection]) :player (component/using (player/new-player) [:output-device]))))