Эта проблема лучше иллюстрируется примером. Я буду использовать Javascript (на самом деле Coffeescript для синтаксиса), но только потому, что Javascript - это просто еще один LISP, верно?Зависимость впрыска в функциональном программировании
Итак, предположим, что я пишу веб-приложение, которое выполняет (очевидно) запросы ajax. Я реализовать функцию, чтобы справиться с этим:
ajaxRequest = (url, params, callback) ->
# implementation goes here
Теперь предположим, что у меня есть сетка, которая извлекает данные с сервера. Где-то в моем коде я должен сделать что-то вроде этого:
userGrid.onMustFetch = ->
ajaxRequest '/fetch/users', { surname: 'MacGyver' }, (data) ->
# fill grid with data
В чем проблема? Если я хочу протестировать реализацию onMustFetch, я не смогу этого сделать, потому что внутри onMustFetch вызывается зависимость, и тестовая среда не может контролировать зависимость.
Чтобы решить эту проблему, я ввожу зависимость в функцию, которую я хочу протестировать. Это означает, что изменение onMustFetch к этому:
userGrid.onMustFetch = (ajaxRequest) ->
ajaxRequest '/fetch/users', { surname: 'MacGyver' }, (data) ->
# fill grid with data
Теперь тестовый код может передать макет из ajaxRequest к onMustFetch и успешно протестировать поведение.
Вундербар, не так ли? Неправильно! Теперь у меня есть вторая проблема: проблема привязки правильного экземпляра ajaxRequest к правильному экземпляру onMustFetch.
В языке, как Java, я мог бы использовать рамки Dependency Injection, чтобы сделать это для меня, и мой код будет выглядеть следующим образом:
class UserGrid {
private AjaxService ajaxService;
@Inject
public UserGrid(AjaxService ajaxService) {
this.ajaxService = ajaxService;
}
public void onMustFetch() {
HashMap<String, String> params = new HashMap<String, String>();
params.put("surname", "MacGyver");
ajaxService.request("/fetch/users", params, new AjaxCallback(data) {
// fill grid with data
});
}
}
Creepy, я знаю ... но на самом деле рамки DI делает всю проводку, поэтому, по крайней мере, эта часть проблемы проще.
Теперь вернемся к нашему веб-приложению и Javascript. Даже если мне удастся всегда вызывать onMustFetch с правом ajaxRequest ссылка (ведь в этом случае это не так сложно сделать), должен быть более простой способ. Когда мой код растет, зависимости увеличиваются. Я могу себе представить, передавая ссылку на ajaxRequest вокруг, но что делать, когда у меня есть securityService, а browserService, а eventBusService, и т.д., и т.д., и т.д.?
Теперь реальный вопрос здесь: Как lisp как языки решают эту проблему управления зависимостями? (Мне кажется, что зависимости должны постоянно меняться во всем приложении, но я уверен, что должен быть лучший способ ...)
Lisp-подобные языки отличаются друг от друга. У них разные системы объектов и т. Д. Этот вопрос действительно касается Javascript: как реализовать шаблон дизайна Java (Injection Dependency) в Javascript. Я удаляю теги вне темы [clojure] [lisp] и [схема]. – Kaz
Речь идет не о javascript. Javascript просто бывает таким, каким я знаком, чтобы выразить эту проблему. Я заинтересован в том, как языки lisp имеют дело с проблемой, поэтому я бы очень хотел, чтобы вы вернули теги. Не стесняйтесь перефразировать вопрос таким образом, который имеет смысл для Lisp, Clojure или Scheme. – RobotFoo