Upload page content

You can upload content for the page named below. If you change the page name, you can also upload content for another page. If the page name is empty, we derive the page name from the file name.

File to load page content from
Page name
Comment

Locked History Actions

scala/DI

ScalaでDI

なぜDIが必要か

DIする理由にも記述したが、これはユニットテストのためであると断言してよい。 DIすれば他にも様々な恩恵が得られるが、それらはむしろ副次的なものである。

いわく、「DIすればアスペクト指向によって、処理をはさみこむことができる」という。デバッグトレースには有効かと思うが、トランザクション管理に使うのは全く賛成できない。トランザクションを意図したコードであれば、それは明示的に記述されるべきであり、そのような意図の無いコードに後付するのは危険が伴う。

「(本番の)実行時に処理を変更できるからだ」という人もいる。これも同じで、そもそもそのような意図のコードであるなら、明示的にそれが記述されるべきである。そのような理由でインターフェースと実装を切り離す必要があるのなら、そもそもインターフェースを明示的に引数として渡すようなコードになっていなければならない。

DIはユニットテストのためにのみ存在するのである。それ以外の点で、もしDIを便利に使える場面があるなら、それはDI以外の方法で実現されなければならない。

DIはどうあるべきか

実戦での Scala: Cake パターンを用いた Dependency Injection (DI)という文書があるが、(私の定義では)これは全くDIになっていない(もちろんGuice以外の方法)。特に、Cake Patternはインターフェースと実装の分離ができているとはとても言えない。

上記を踏まえて、DIがどうあるべきかを考えてみると、私の意見としては以下である。

  • テストされるコードとは無関係の場所でインターフェースと実装を結びつけることができること。
  • 本番環境ではデフォルトの実装が、特別な操作無しに暗黙的に選択されていること(GuiceのImplementedByのようなもの)。

  • インジェクションされるかサービスロケータとして実現されるかはどちらでも構わない。
  • しかしむしろ、サービスロケータの方が理解しやすく、制限も緩いので望ましい。
  • DIするときの記述はできるだけ簡単であること。「new コンストラクタ(引数)」と同様の短い記述で済ませられるのが望ましい。
  • 特に注入されることを意図していないクラスの取得(生成)でも同じ記述ができること。
  • DIはユニットテストのためなのだから、モックが簡単にできること。
  • DIライブラリは小さくなければならないし、小さくすべきである。GuiceでさえAndroid向けには大きすぎる。

liftのDIを調べてみる

もちろんこれは、狭義でのDIではなく、サービスロケータと呼ぶべきものである。作者も「どうとでも呼んでくれ」と言っている。

むしろ私にとってはそのほうが都合がよいのだ。狭義の「インジェクション」など必要ない。

続く。

その他のScala専用DI