Protocol + Client Namespace + Multimethod
You could use a protocol to define the abstraction, except connect
, which is a multimethod:
1 (ns stadig.storage.protocol 2 (:refer-clojure :exclude [get])) 3 4 (defprotocol IStorage 5 (get [this bucket key]) 6 (put [this bucket key value]) 7 (delete [this bucket key]) 8 (close [this])) 9 10 (defmulti connect :backend)
Implement the protocol and multimethod for each backend:
1 (ns stadig.storage.s3 2 (:require 3 [aws.sdk.s3 :as s3] 4 [stadig.storage.protocol :as proto])) 5 6 (defrecord S3Storage 7 [access-key secret-key] 8 proto/IStorage 9 (get [this bucket key] 10 (s3/get-object this bucket key)) 11 (put [this bucket key value] 12 ...