«Инверсия контроля» широко используется в Лиспе.Это совершенно просто, поскольку функции и замыкания являются объектами первого класса.
Внедрение зависимостей тривиально.Классы и функции могут быть сконфигурированы с помощью символов и классов первого класса.
Обычно вам не требуется «каркас» для IoC или DI в Common Lisp, так как множество функций для настройки и параметризации приложений и библиотеквстроенный.
«первый класс» означает, что что-то может храниться в переменных, передаваться в качестве аргументов или возвращаться в качестве результатов.
В таком языке, как Common Lisp, функции и классы являются объектами первого класса,Кроме того, для развязки с помощью позднего связывания вы можете использовать вместо символов символы.Система объектов Common Lisp знает мета-классы и символы как имена для классов.Даже общие функции и методы являются объектами и имеют мета-классы.
Если concurrent-secure-server
- это класс, а default-response
- это функция, вы можете сделать, например:
(make-instance 'web-services
:server-class 'concurrent-secure-server
:default-response-function 'default-reponse)
Вышеиспользует символ в качестве имени для класса и функции.Если функция получает новую версию, веб-служба может вызвать новую позже.
В качестве альтернативы:
(make-instance 'web-services
:server-class (find-class 'concurrent-secure-server)
:default-response-function #'default-reponse)
В вышеупомянутом случае мы передаем объект класса и объект функции.
В программных модулях Common Lisp могут быть глобальные переменные, которые вы можете установить с правильной информацией:
(defvar *default-server-class* 'concurrent-secure-server)
В качестве альтернативы вы можете установить их в слоты, как показано ниже.
(defclass server-object ()
((default-response-function
:initarg :default-response-function
:initform *server-default-response-function*)))
(defvar *my-server*
(make-instance 'server-object
:default-response-function 'my-default-response-function))
Вы даже можете создавать объекты, а затем изменять их класс на этапе настройки.Common Lisp Object System позволяет вам изменять классы и обновлять существующие объекты.
Если вы создаете экземпляр, вы можете быть настолько гибкими, насколько захотите:
- вы можетепередавая класс
- , вы можете передавать аргументы
Примерно так:
(let ((my-class 'foo-class)
(my-args `(:response-function ',*some-reponse-function)))
(apply #'make-instance my-class my-args))
Иногда вы видите библиотеки Lisp, которые вычисляют такие списки аргументов во время выполнения,
Еще одна вещь, где вы можете конфигурировать приложения на Лиспе во время выполнения, - это общие функции.Общие функции позволяют: before,: after и: around методы - они даже позволяют использовать ваши собственные схемы вызовов.Таким образом, используя ваши собственные классы, наследуемые от других классов и классов смешивания, универсальная функция переконфигурируется.Это похоже на то, что у вас есть встроенные базовые механизмы Аспектно-ориентированного программирования.
Для людей, интересующихся этими более продвинутыми объектно-ориентированными концепциями, есть некоторая литература Xerox PARC, где эти проблемы были исследованы при CLOSбыл создан.Тогда он назывался «Открытая реализация»:
http://www2.parc.com/csl/groups/sda/publications.shtml
В подходе открытой реализации модули предоставляют своим клиентам индивидуальный контроль над собственной стратегией реализации модуля.Это позволяет клиенту адаптировать стратегию реализации модуля в соответствии с его потребностями, эффективно делая модуль более пригодным для повторного использования, а клиентский код - более простым.Этот контроль предоставляется клиентам через хорошо продуманный вспомогательный интерфейс.
Одна вещь, которая вам не нужна: XML.Common Lisp - это собственный язык конфигурации.Написание расширений для более легкой настройки может быть сделано, например, с помощью макросов.Загрузка этих конфигураций может быть легко выполнена с помощью LOAD
.