DIPは間違っている



書籍「アジャイルソフトウェア開発の奥義」(ロバートCマーチン著、瀬谷啓介訳)の第一版のP163からの記述「依存関係逆転の原則(DIP)」は間違っているか、あるいは議論に混乱が見られる。ネット上にはこれを無批判に引用する日本語記事が多々存在するのだが、彼らは全くその内容を吟味も理解もしていないと思われる。

DIP原則とは

著者の説明はこうである。

  • 上位モジュールは下位モジュールに依存してはならない。どちらのモジュールも抽象に依存すべきである。
  • 「抽象」はその実装の詳細に依存してはならない。実装の詳細が「抽象」に依存すべきである。

という。ここで、「上位モジュールは下位モジュールに依存してはならない」は間違いである。

そもそも上位・下位モジュールの定義が明確ではない(「アプリケーションの方針を決めている上位モジュール、実装の詳細を担当する下位レベルのモジュール」のみの説明)のだが、著者の意図としてはこうだろう。

  • 上位モジュール:使う側
  • 下位モジュール:使われる側

反論1

これに対する反論の一つとしてはこうだ。あるアプリケーションの構築と同時に、他のアプリケーションにも使用可能なライブラリを開発することにしたとする。こうした場合、これらのライブラリが上位モジュールである「アプリケーション」に依存してしまっては可搬性がなくなってしまう。したがって、「ライブラリ部分」と、その上位である「それ以外のアプリケーション部分」は、上位が下位に依存するという構造にならざるを得ない。

そしてこれは、同著で後述されている(P331)安定依存の原則(SRP)にも合致していると考えられる。つまり、著者自身が矛盾しているのである。

反論2

しかし、「この原則はライブラリ作成のようなケースを除外している」と反論されてしまうかもしれない。それでは以下のようなケースはどうだろうか。

例えば、三層アーキテクチャを考えてみる。これはUI層、ビジネスロジック層、データベース層に分かれる。一般的には、これらはソケットを介した何らかのプロトコルによって接続される複数のプログラムになると思われるが、別に一つのアプリとして開発してはいけない法はない。

この場合、UI層がビジネスロジック層に依存することになるが、これがいけないという理由は全く無いどころか、むしろ推奨されるべきものである。「そもそも我々が再利用したいと思っているのは、方針を決めている上位モジュールの方である」と著者は主張するが、そうではない。下位であるビジネスロジックの方を再利用したいこと、あるいは再利用すべきことは明らかであろう。

著者の想定は時代錯誤

反論2からもわかるように、著者の想定はそもそも古すぎるのである。どういうわけか、この章で著者は、”’20年以上も前の古めかしいソフトウェア設計を前提にしている”’のである。著者はP164で主張する「事実、従来の手法の目標の一つは、上位モジュールから下位モジュールの呼び出し方を定義したプログラムの階層構造を作ることなのだ」。これはCUI時代のプログラムの構造であって、現代のソフトウェアではそうとはいえない。現代のプログラム、つまりGUIプログラムでは既に制御構造自体が逆転しているのであって、DIPは成立しないのである。

著者は、このような事実を無視し、自説を強調するためにわざわざおかしな例を出している。

例1

P165で、わざわざ耳慣れないレイヤー「Policy Layer」「Mechanism Layer」「Utility Layer」を出しているのはそのためである。こうしたレイヤ構造はかなり一般的ではない。著者は持論を証明したいが為に、一般的ではないレイヤ構造をわざわざ引き合いに出しているのである。

例2

プログラム例も同じである。P113のCopyプログラムも、P170の暖炉の例も、GUI部分は含まれていない。たしかに、この例自体は著者の主張を裏付けるものであって、「正しい」のではあるが、やはり「既に制御が逆転した」GUIプログラムについては完全に無視されている。

所有権の逆転とハリウッド原則

これについてもおかしな主張が見られる(P166)。「ハリウッド原則」とはIoC(Inversion of Control~制御の反転)で使われる用語であり、典型的にはCUIからGUIへの移行によって、制御がこれまでの呼ぶ方式から呼び出される方式に変更したことを指すものである。

インターフェースの所有権がどう変更されようと、同じアプリ内において上位モジュールから下位モジュールを呼び出すことには変わりがなく、これはIoCとは無関係であるし、ハリウッド原則とも無関係である。