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

Dependency management in Clojure

Avatar for schaueho 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

Avatar for schaueho

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]))))