4

「ハッカーになる方法」というESRのエッセーを読んだ。数年前(私のプロフィールにリンクがあります)、EricはLISPの学習を提案しました。まあ、私はかなり長い間LISPを学んでいます。私はそれが好きで、それを使ってWebアプリケーションを書くことにしました。LISPの依存性注入(とIoCコンテナに関する)のポイント

私はしばらくの間Springを使用していますので、分離されたコンポーネントを記述し、IoCコンテナと真っ直ぐな注入を使用して一緒に接着することをお勧めします。私はGoogle上でパワーサーチを行い、LISPに実装されたそのようなアイデアはないことが判明しました。私は何かが恋しいですか? LISPにこのコンセプトの良い実装がありますか、それとも私にはまだわからない何らかの理由でそれを使用している点はありませんか?

+2

Common Lispは動的に型定義され、フル機能の匿名関数を持ち、OOは汎用関数に基づいています。私はIoC/DIパターンの経験が十分ではありませんが、これは完全な答えにはなりますが、言語自体には含まれていませんか? – Ramarren

+0

これは私が答えを得たいという質問です。 :) –

+1

@Ramarren、dependency injectionは、単にソフトウェアビルディングブロックが依存関係自体を求めるのではなく、「外部から」受け取ることを意味します。私の意見では、このようなデザインパターンは、ダイナミックな型指定や匿名の機能ではなく、言語の機能に包含されることはありません。オブジェクトグラフを手でまとめることができるので、* I *包含できるものはIoCコンテナです。たぶんLispで簡単にできるのは、人々が単にそれを行うために余分なライブラリを必要としないということだけです。 (私はObjective-CでDIを手で幸せにしています) – zoul

答えて

18

'Inversion of control'はLispで広く使用されています。関数とクロージャーはファーストクラスのオブジェクトであるため、完全にシンプルです。

依存性注入は自明ではありません。クラスおよびファンクションは、シンボルおよびファーストクラスのクラスを使用して構成できます。

アプリケーションやライブラリを設定し、パラメータ化する多くの機能が内蔵されているのであなたは通常、Common Lispの中のIoCまたはDIのための「枠組み」を必要としません。

「ファーストクラス」は何かができることを意味します変数に格納され、引数として渡されるか、結果として返されます。

Common Lispのような言語では、関数とクラスはファーストクラスのオブジェクトです。レイトバインディングによるデカップリングのためのプラスではなく、代わりにシンボルを名前として使用できます。 Common Lisp Object Systemは、クラスの名前としてメタクラスとシンボルを認識します。ジェネリック関数とメソッドさえもオブジェクトであり、メタクラスを持っています。 concurrent-secure-serverがクラスであるとdefault-responseが関数である場合

、あなたは、たとえば行うことができます。

(make-instance 'web-services 
       :server-class 'concurrent-secure-server 
       :default-response-function 'default-reponse) 

上記は、クラスや関数の名前などの記号を使用しています。関数が新しいバージョンを取得した場合、Webサービスは新しいバージョンを後で呼び出すことがあります。

あるいは:上記の場合

(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ライブラリが表示されることがあります。

    実行時にLispアプリケーションを設定できるもう一つの点は、汎用関数によるものです。一般的な関数は:before、:afterおよび:aroundメソッドを許可しています。独自のカスタム呼び出しスキーマを許可することさえできます。したがって、他のクラスやmixinクラスを継承する独自のクラスを使用することで、ジェネリック関数が再構成されます。これは、アスペクト指向プログラミングの基本的な仕組みが組み込まれているようです。

    これらの高度なオブジェクト指向の概念に興味がある人には、CLOSの作成時にこれらの問題が調査されたXerox PARCの文献があります。次に、これを「オープンな実装」と呼ばれました:オープン実装のアプローチで

    http://www2.parc.com/csl/groups/sda/publications.shtml

    、モジュールは、モジュールの独自の実装戦略を超える顧客が個々のコントロールが可能。これにより、クライアントは、モジュールの実装戦略を調整して、ニーズに合わせて、モジュールをより再利用可能にし、クライアントコードをよりシンプルにすることができます。この制御は、うまく設計された補助インタフェースを介してクライアントに提供されます。

    あなたが必要としないことのひとつ:XML。 Common Lispは独自の設定言語です。より簡単な構成のためのエクステンションの作成は、例えばマクロを介して行うことができる。これらの設定のロードはLOADで簡単に行うことができます。

  • +0

    これはまさに私が欲しかったことです、ありがとう! –

    +0

    答えのリンクは、メインのparcウェブサイトへのリダイレクトにすぎません。 https://web.archive.org/web/20110906111530/http://www2.parc.com/csl/groups/sda/publications.shtmlで元のコンテンツに引き続きアクセスできます。 –

    3

    実際、IoCは、JavaやLispだけでなく、ほとんどのWebフレームワークの構築原則です。 DIを考慮すると、Rammarenが指摘したように、それはLispのような動的言語の暗黙のパターンです。 Hello WorldのアプリケーションをSpringRestas(十分にサポートされているCL Webフレームワークの1つ)と比較すると、あなた自身がそれを見ることができます。 Lispでの空想的な型/クラス/インタフェース宣言の必要がないことを除いて、同じパターンがあることがわかります。