Краткий обзор функционирует или функциональные интерфейсы в Clojure?

Во многих случаях у меня есть набор функций, которые я хотел бы реализовать по-разному. Самый очевидный пример этого состоял бы в том, чтобы абстрагировать от определенных баз данных. На объектно-ориентированном языке Вы использовали бы интерфейс для этого:

interface DB {
  ResultSet query(String query);
  void persist(Object o);
  ...
}

В коде speudo я хотел бы сделать что-то вроде этого:

(ns dbbackend)

(abstractfn query [q])
(abstractfn persist! [o])

И затем реализации для каждой базы данных:

(ns dbbackend.mysql :implements dbbackend)
(defn query [q] ...)
(defn persist! [o] ...)

Мне не совсем ясно, что лучшая практика должна сделать что-то подобное на функциональном языке, конкретно Clojure. Я должен использовать мультиметоды для этого?

9
задан Zef Hemel 6 January 2010 в 07:16
поделиться

2 ответа

Теперь, когда была выпущена версия 1.1 Clojure , возможно, пора заглянуть в будущее.

Типы данных и протоколы , которые в настоящее время доступны только в новой главной ветке на github , могут быть именно тем, что вы ищете.

(defprotocol DB
  (query   [backend query])
  (persist [backend object]))

(deftype MySQLBackend []
  DB
  (query   [query] ...)
  (persist [object] ...))
11
ответ дан 4 December 2019 в 12:18
поделиться
[

]Для препротокольной версии Clojure:[

] [

]Интерфейс:[

] [
(ns dbbackend)

(defmulti query
  {:arglists '([c q])}
  suitable-dispatch-fn)

(defmulti persist!
  {:arglists '([c o])}
  suitable-dispatch-fn)
] [

]Реализация:[

] [
(ns dbbackend.mysql
  (:requires dbbackend))

(defmethod query com.mysql.jdbc.Connection
  [c q]
  ...)

(defmethod persist! com.mysql.jdbc.Connection
  [c o]
  ...)
] [

]Использование:[

] [
(ns user
  (:require dbbackend dbbackend.mysql))

(def mysql-connection (connect-to-mysql))
(query mysql-connection some-query)
] [

]Реальный пример такого подхода можно найти под капотом ClojureQL.[

].
6
ответ дан 4 December 2019 в 12:18
поделиться
Другие вопросы по тегам:

Похожие вопросы: