2013-03-24 3 views
5

http://mindbat.com/2013/03/clojurewest-2013-day-one-notes/ पर एक नोट है कि पढ़ता है:एक Compojure आवेदन में वैश्विक डेटा से छुटकारा पाने के लिए कैसे

  • शीर्ष स्तर पर refs और परमाणुओं def'ing मूल रूप से एकमात्र के माध्यम से वैश्विक परिवर्तनशील राज्य है,
  • से बचने के लिए कृपया
  • राज्य चर का उपयोग करना चाहते वापसी के निर्माता कार्यों उपयोग करने की अनुशंसा, तो प्रत्येक समारोह के लिए साथ है कि राज्य पारित

मुझे लगता है कि यह अच्छी सलाह है, लेकिन मैं पूरी तरह से यकीन है कि कैसे करने के लिए नहीं कर रहा हूँ इसे एक अंगूठी/कंपोज़र एप्लिकेशन में कार्यान्वित करें। क्या कोई इस बात का ठोस उदाहरण दे सकता है कि यह कैसे काम करेगा?

मुझे विशेष रूप से दिलचस्पी है कि defroutes, init और app इस तरह से एक साथ कैसे जुड़ें और उस दायरे में वैश्विक चर से छुटकारा पाएं।

उत्तर

2

ऐसे कई मामले हैं, जहां आप वैश्विक राज्य की जरूरत है इसलिए आप इसे टाल नहीं सकते, आप क्या कर सकते है इसे ठीक से प्रबंधन और मुझे लगता है कि है कि 2 अंक के बारे में क्या बात है:

नहीं

एक अच्छा तरीका:

(ns data) 
(def users (atom [])) 

(ns pages) 
(defn home [] 
    (do-something data/@users) 

(defn save [] 
    (let [u @users] 
     (swap! data/users ....) 

अच्छा तरीका:

(ns data) 
(def- users (atom [])) 
(defn get-users [] @users) 
(defn update-user [user] (swap! @users ...)) 

(ns pages) 
; use the functions exposed by data ns to interact with data rather then poking the atom directly. 

मूल रूप से राज्य के किसी भी प्रकार के इस्तेमाल के सभी दूसरे से दूर निकाला जाना चाहिए आवेदन के कुछ हिस्सों। आपके सभी व्यावसायिक तर्क फ़ंक्शन को राज्य को पैरामीटर के रूप में ले जाना चाहिए और राज्य को चुनने और इसे सीधे अपडेट करने के बजाय नया राज्य वापस करना चाहिए।

(ns state.core) 

(defn create-user-module [] (atom [])) 

(defn add-user [module user] 
    (swap! module conj user)) 

(defn get-users [module] 
    @module) 

अब कार्यों है कि राज्य में हेरफेर के रूप में अपने "मूल" में कोई वैश्विक स्थिति है एक पैरामीटर के रूप में यह प्राप्त करने की उम्मीद:

+0

वाई! यह अच्छा दृष्टिकोण है। – hsestupin

+0

@hsestupin: क्या यह एक प्रश्न या पुष्टि है :) – Ankur

+0

पुष्टि। मेरा मतलब था कि मैं उस तरह के दृष्टिकोण से पूरी तरह सहमत हूं जब राज्य सीधे संदर्भ से बदला नहीं जा सकता था। – hsestupin

5

मैं स्टुअर्ट की बात से क्या समझते हैं कुछ इस तरह है। ये आसान परीक्षण की अनुमति देता है क्योंकि आप प्रत्येक परीक्षण के लिए "उपयोगकर्ता-मॉड्यूल" का एक नया उदाहरण बना सकते हैं। साथ ही, इस मॉड्यूल के क्लाइंट को इस बात की परवाह नहीं करनी चाहिए कि उन्हें बनाने-उपयोगकर्ता-मॉड्यूल फ़ंक्शन में क्या मिलता है, उन्हें इसे जांचने के बिना इसे पास करना चाहिए, इस तरह आप जब भी चाहें उपयोगकर्ता मॉड्यूल कार्यान्वयन को बदल सकते हैं। स्टुअर्ट भी उन मॉड्यूल के लिए प्रोटोकॉल बनाने के बारे में बात करता है यदि आप एक से अधिक कार्यान्वयन करने जा रहे हैं।

अपने सवाल का जवाब देने की कोशिश कर रहा, एक अंगूठी अनुकूलक सिर्फ 1 परम के एक समारोह है, और compojure सिर्फ एक मार्ग पुस्तकालय है, तो आप की तरह बंद का उपयोग कर एक वेब एप्लिकेशन बना सकते हैं:

(ns state.web 
    (:use compojure.core) 
    (:require [state.core :as core])) 

(defn web-module [user-module] 
    (routes 
    (GET "/all" [] (core/get-users user-module)))) 

अब आप एक वेबपैप बनाने के लिए वेब-मॉड्यूल को कॉल कर सकते हैं, पैरामीटर के रूप में पारित निर्भरता की आवश्यकता होती है। बेशक आप अभी भी सही उपयोगकर्ता के मॉड्यूल के साथ वेब अनुप्रयोग बनाने के लिए किसी की जरूरत है ताकि आप सिर्फ एक "मुख्य" समारोह है कि एक साथ तारों सब कुछ की जरूरत है:

(ns state.main 
    (:require state.core 
      state.web) 
    (:use ring.adapter.jetty)) 

(defn start [] 
    (let [user-module (state.core/create-user-module) 
     web-module (state.web/web-module user-module)] 
    (run-jetty web-module {:port 3000 :join? false}))) 

(defn stop [app] 
    (.stop app)) 

start अपने अनुप्रयोग main विधि से बुलाया जाएगा। इसका मतलब यह है कि आपको लीन-रन प्लगइन पर स्विच करने की आवश्यकता है।

अब, यह देखते हुए कि आप init (लीन रिंग प्लगइन से मुझे लगता है) से पूछ रहे हैं, मुझे लगता है कि आप अपने वेबपैप को एक कंटेनर में तैनात करने की योजना बना रहे हैं।

(ns state.web 
    (:use compojure.core) 
    (:require [state.core :as core])) 

(def module-deps (atom {}) 

(defn init-app [] (swap! module-deps conj [:user-module (core/create-user-module)])) 

(defroutes web-module [] 
    (GET "/all" [] (core/get-users (:user-module @module-deps)))) 

यह अभी भी अपने मूल इसका मतलब है कि: lein अंगूठी प्लगइन जावा सर्वलेट परिवार कल्याण की कमी के भीतर और हैंडलर समाप्त होता है एक जावा सर्वलेट का संकलन किया है कि काम करने के लिए है के रूप में, सबसे अच्छा आप शायद कर सकते हैं ऐसा ही कुछ है नेमस्पेस परीक्षण करना आसान है, लेकिन आपके पास अभी भी वेब नेमस्पेस में वैश्विक स्थिति है, लेकिन मुझे लगता है कि यह "ठीक से" encapsulated है और यदि आप जावा कंटेनर का उपयोग करना है तो शायद पर्याप्त है।

और यह एक और तर्क है कि लाइब्रेरी फ्रेमवर्क की तुलना में "बेहतर" क्यों हैं :)

संबंधित मुद्दे