Dependency injection - это техническая разработка программного обеспечения, целью которой является уменьшение взаимозависимости между двумя подсистемами программы. Очень важная деталь этого метода является то, что она включает в себя не два, а три подсистемы:
- сервис,
- клиент, используя
- инжектор, чья обязанность заключается в том, чтобы подготовить службы для клиент.
Последняя подсистема, с ее ответственностью, часто упускается из виду, но имеет решающее значение: это означает, что клиент знает об услуге как о своем открытом интерфейсе, а это означает, что можно легко использовать посмеянный сервис для тестирования клиент.
Предположим, что мы пишем приложение, сообщающееся с хранилищем значений ключей по сети. Ключ-значение магазин имеет следующую подпись:
module type AbstractKeyValueStoreService =
sig
exception NetworkError
type t
val list : t -> string
val find : t -> string -> string option
val set : t -> string -> string -> unit
end
Если мы напишем код клиента в качестве клиента параметризовать модуль типа AbstractKeyValueStoreService мы можем проверить устойчивость нашего приложения к сетевым ошибкам при использовании установить функции, просто предоставляя высмеивали обслуживание, без необходимости фактически создать ошибку сети:
module KeyValueStoreServiceFailingOnSet =
struct
exception NetworkError
type t = unit
let list() = [ "a"; "b"]
let find = function
| "a" -> Some("x")
| "b" -> Some("y")
| _ -> None
let set _ _ = raise NetworkError
end
Если наш клиент записываются как функтор параметрического модулем типа AbstractKeyValueStoreService легко написать тесты для этого программного компонента, где издевательская служба выполняет более или менее сложный сценарий взаимодействия с клиентом.
Использование модулей в качестве параметров не может быть «земной тряской идеей», тем не менее важно знать, как эта идея может быть использована для решения важных проблем разработки программного обеспечения. Это то, что делают авторы «реального мира OCaml».