سؤال

وأنا أبحث عن وسيلة الاصطلاحية (ق) لتحديد واجهة في كلوجر التي يمكن تنفيذها من قبل "مزود خدمة" خارجي. أن طلبي تحديد مكان ومثيل وحدة مزود الخدمة في وقت وتفويض المسؤوليات معينة لذلك.

ودعونا نقول، على سبيل المثال، أنني تنفيذ آلية RPC وأريد أن تسمح الوسيطة مخصصة ليتم حقنه في وقت التكوين. هذه الوسيطة يمكن ما قبل عملية الرسالة، تجاهل الرسائل، والتفاف معالج الرسالة مع قطع الأشجار، وما إلى ذلك.

وأنا أعرف عدة طرق للقيام بذلك إذا كنت تعود الى انعكاس جافا، ولكن نرى أن تنفيذ ذلك في كلوجر من شأنه أن يساعد فهمي.

و(لاحظ، أنا باستخدام SPI في الشعور العام هنا، لا تشير تحديدا إلى الطريقة التي تم تعريفها في في JAR ملف مواصفات )

والشكر

هل كانت مفيدة؟

المحلول

وكلوجر هي لغة ديناميكية للغاية: أي شيء تقريبا التي يمكن القيام به في وقت الترجمة يمكن القيام به في وقت التشغيل. بك "تكوين النشر" يمكن ببساطة أن تكون ملف مصدر كلوجر أن يحصل على تحميل في التطبيق في وقت التشغيل. مجرد دعوة (تحميل "بلدي config.clj"). لاحظ أنه يمكنك حتى تجاوز وظائف في نطاق ديناميكي خاص إذا كنت تريد حقا، لذلك يمكنك لف <م> أي وظيفة (بما في ذلك وظائف أساسية) مع بعضها البعض التي تقول بتسجيل حججهم، قيمة الإرجاع والى متى أخذوا لتشغيل. إلقاء نظرة على clojure.contrib.trace مثالا لكيفية القيام بذلك.

نصائح أخرى

Compojure الاستخدامات <لأ href = "http://compojure.org/docs/middleware" يختلط = "نوفولو noreferrer"> "الوسيطة" للتعامل مع طلبات HTTP، قد نظر في تنفيذه. A "معالج" في Compojure هو دالة التي تأخذ الطلب وإرجاع استجابة. (طلب والاستجابة على حد سواء كلوجر التجزئة خرائط.) "الوسيطة" هو دالة التي تأخذ دالة معالج، وإرجاع دالة معالج مختلفة. الوسيطة يمكن أن يغير الطلب، وردا على ذلك، أو على حد سواء؛ يمكن استدعاء معالج انها مرت عليه (مرارا وتكرارا إذا أرادت) أو ماس كهربائى وتجاهل معالج، وما إلى ذلك يمكنك لف معالجات في معالجات أخرى بهذه الطريقة في أي مجموعة.

وبفضل وظائف كونها كائنات من الدرجة الأولى، وهذا هو خفيفة الوزن جدا وسهلة التنفيذ والاستخدام. ومع ذلك فإنه لا تفرض أي شيء في وقت الترجمة كما ستحصل من واجهة جافا. الأمر كله مسألة الاتفاقيات وبطة الكتابة التالية. بروتوكولات قد تكون جيدة لهذه المهمة في نهاية المطاف، لكنها لن لتكون متاحة لفترة من الوقت (ربما في كلوجر 2.0؟)

ولست متأكدا إذا كان هذا هو ما تريد، ولكن هنا هو نسخة بدائية جدا:

;; Handler
(defn default [msg]
  {:from "Server"
   :to (:from msg)
   :response "Hi there."})

;; Middleware
(defn logger [handler]
  (fn [msg]
    (println "LOGGING MESSAGE:" (pr-str msg))
    (handler msg)))

(defn datestamper [handler]
  (fn [msg]
    (assoc (handler msg)
      :datestamp (.getTime (java.util.Calendar/getInstance)))))

(defn short-circuit [handler]
  (fn [msg]
    {:from "Ninja"
     :to (:from msg)
     :response "I intercepted your message."}))

;; This would do something with a response (send it to a remote server etc.)
(defn do-something [response]
  (println ">>>> Response:" (pr-str response)))

;; Given a message and maybe a handler, handle the message
(defn process-message
  ([msg] (process-message msg identity))
  ([msg handler]
     (do-something ((-> default handler) msg))))

وبعد ذلك:

user> (def msg {:from "Chester" :to "Server" :message "Hello?"})
#'user/msg
user> (process-message msg)
>>>> Response: {:from "Server", :to "Chester", :response "Hi there."}
nil
user> (process-message msg logger)
LOGGING MESSAGE: {:from "Chester", :to "Server", :message "Hello?"}
>>>> Response: {:from "Server", :to "Chester", :response "Hi there."}
nil
user> (process-message msg (comp logger datestamper))
LOGGING MESSAGE: {:from "Chester", :to "Server", :message "Hello?"}
>>>> Response: {:datestamp #<Date Fri Nov 27 17:50:29 PST 2009>, :from "Server", :to "Chester", :response "Hi there."}
nil
user> (process-message msg (comp short-circuit logger datestamper))
>>>> Response: {:from "Ninja", :to "Chester", :response "I intercepted your message."}
nil
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top