2013-12-19 2 views
7

Ich verwende Datomic in mehreren Projekten und es ist Zeit, den gesamten Code in eine kleine Utilities-Bibliothek zu verschieben.Wie behandelt man eine Variable in einer Bibliothek, die außerhalb davon gesetzt werden muss?

Eine Herausforderung besteht darin, mit einer gemeinsamen Datenbank uri umzugehen, von der die meisten Operationen abhängen, die jedoch vom Projekt mithilfe der Bibliothek festgelegt werden muss. Ich frage mich, ob es einen gut etablierten Weg dafür gibt. Hier sind einige Alternativen dachte ich habe über:

  • Dropping uri Symbol in der Bibliothek und das Hinzufügen der uri als Argument für jede Funktion, die auf die Datenbank zugreift

  • es über alter-var-root zu ändern oder ähnlich Mechanismus, in einer Funktion init

  • es in der Bibliothek als ein dynamisches var *uri* und überschreibt den Wert in einer hoffentlich kleinen Adapterschicht wie

    Keeping

    (def my-url ... bla ...)

    (my-fun [args] (mit-datomic-uri my-uri (gilt Bibliothek/my-Spaß args)) DEFN

  • Keeping uri als ein Atom in der Bibliothek

+0

Erwarten Sie, dass Benutzer die URI zur Laufzeit ändern möchten, oder muss sie nur einmal für ein bestimmtes Projekt definiert werden? –

+0

Nicht zur Laufzeit, @OmriBernstein. Es gibt eine Datenbank für Tests und eine für die Produktion. – konr

Antwort

4

Es gab eine Präsentation von Stuart Sierra letzten Clojure/West, genannt Clojure in the Large, die sich mit Design-Muster für größere Clojure Anwendungen.

Einer von denen war das Problem, das Sie beschreiben.

Um Tipps in Bezug auf das Problem bei der Hand zusammenfassen:

1 Klar Konstruktor

So haben Sie einen gut definierten Ausgangszustand.

(defn make-connection [uri] 
     {:uri uri 
     ...} 

2 Make Abhängigkeiten klar

(defn update-db [connection] 
    ... 

3 Es ist einfacher,

(deftest t-update 
    (let [conn (make-connection)] 
    (is (= ... (update-db conn))))) 

4 Safer zu testen

(require ... :reload) 

Keeping uri in einem variabl nachladen e, später gebunden zu werden, ist ziemlich allgemein, aber führt versteckte Abhängigkeiten ein, auch angenommen body beginnt und endet auf einem einzelnen Thread.

Beobachten Sie das Gespräch, viele weitere Tipps zum Design.

+1

Es gibt auch diese Bibliothek von ihm https://github.com/stuartsierra/component – konr

3

Mein Gefühl ist, die meisten datomic Codes zu halten, wie frei von implizitem Staat wie möglich.

Haben Abfragefunktionen eine Datenbank Wert. Haben Schreibfunktionen (transact) nehmen Sie eine Datenbankverbindung. Das maximiert die potenzielle Wiederverwendung und vermeidet implizite Annahmen, wie immer nur mit einer Datenbankverbindung zu sprechen oder versehentlich implizit fest codierte Abfragefunktionen, um nur mit dem aktuellen Datenbankwert zu arbeiten - im Gegensatz zu früheren (as-of) oder zukünftigen (with) Datenbankwerten.

Das Koordinieren einer einzelnen gemeinsamen Verbindung für den Standard-Anwendungsfall der Bibliothek wird dann zur Aufgabe eines kleinen zusätzlichen Namensraums. Die Verwendung eines Atoms ist hier sinnvoll, um die URI oder Verbindung zu halten. Einige Komfortmakros, vielleicht with-connection und with-current-db genannt, könnten dann die Hauptbibliotheksfunktionen umbrechen, wenn das manuelle Codieren und Übergeben von Verbindungs- und Datenbankwerten ein Ärgernis darstellt.

Verwandte Themen