この問題は、例でよりよく説明されています。Javascript (実際には構文上の目的で Coffeescript) を使用しますが、Javascript は別のLISPにすぎないからですよね?
それで、(明らかに) ajax リクエストを行う Web アプリを書いているとします。それを処理する関数を実装します。
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 のような言語では、依存性注入フレームワークを使用してこれを行うことができ、私のコードは次のようになります。
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
});
}
}
気味が悪い、私は知っています...しかし、実際にはDIフレームワークがすべての配線を行うので、少なくとも問題のその部分は簡単です.
ここで、Web アプリと Javascript に戻ります。適切なajaxRequest参照を使用して常にonMustFetchを正常に呼び出すことができたとしても(結局のところ、この場合はそれほど難しくありません)、もっと簡単な方法があるはずです。コードが大きくなると、依存関係が増加します。ajaxRequestの参照を渡すことは想像できますが、securityService、browserService、eventBusServiceなどがある場合はどうでしょうか?
ここで本当の質問です: Lisp のような言語は依存関係を管理するというこの問題をどのように解決しますか? (依存関係はアプリケーション全体に渡され続ける必要があるように思えますが、もっと良い方法があるはずです...)