2007年07月20日

インターフェイス分離の原則

 インターフェイス分離の原則は、英語ではthe Interface Segregation Principleと言われ、ISPと略されます。

 これは、クライアントに、クライアントが依存しないメソッドへの依存性を強制してはならないという原則です。

 例によって、一見しただけでは意味がよくわかりませんね。
詳しくお話ししてみましょう。

コンテンツ

  1. コミュニケーションの分離
  2. 道具のインターフェイス
  3. 原則の関連
  4. ソフトウェア開発者の方のための追記
  5. オススメ

コミュニケーションの分離

 上司や先生など目上の人と話すときと、家族や友人など親しい人と話すとき、あるいは恋人や配偶者などさらに親しい人と話すとき。
同じことを話すのでも、相手によって話し方が違いますよね。

 話し方というのは、人間同士のコミュニケーションのためのインターフェイスです。
あなたという一人の人間が、相手によって使い分けるための、複数のインターフェイスを持っているわけです。

 相手によって話し方が違うということは、相手によって違うインターフェイスを使い分けているということです。
インターフェイスは、それぞれ独立していますので、変更の影響を受けません
変更の影響を受けない?どういうことでしょう。

 例えば、人事異動によって上司が変わったとします。
新しい上司は、前の上司よりもかなり礼儀に厳しい人で、以前とは比べ物にならないくらい、話し方に気をつけなければなりません。
あなたの上司に対するインターフェイスは、このことで変更を余儀なくされます。
でも、そのせいで、家族との話し方まで変わったりはしませんよね。
あなたの、それぞれに対するインターフェイスが分離されているからです。
人間というのは、なんて柔軟にできているのでしょう。

道具のインターフェイス

 これに対して、人間が作った道具には、それほど柔軟でないものがけっこうあります。
例えば、お財布。
お財布というものは、もともとは、単にお金を入れるためだけのものですよね。
でも、世の中にカードというものが普及したことにより、たいていのお財布は、カード入れを備えるようになりました。

 高機能なお財布ほど、たくさんのカード入れを持っています。
すごいのになると、クレジットカードやキャッシュカードを入れる場所の他、免許を入れる場所、定期を入れる場所など、いちいち、専用のぴったりサイズの入れ場所が用意されてたりします。

 それぞれの入れ場所は、ひとつひとつが、対応するカードに対するインターフェイスです。
  • それぞれのカードにぴったりのサイズ
  • 必要なものについては、入れたままでも見えるように透明になっていること
  • よく取り出すものについては、取り出しやすいようにスリットが入っていること
これらのことが、インターフェイスなのです。
便利なのですが、これは肥大化したインターフェイスです。

 車や自転車で通う人は、定期を入れるところは使わないですよね。
また、クレジットカードやキャッシュカードを持ち歩かない人は、それらの入れ場所は使いません。
免許を持っていない人は、免許を入れる場所は使いません。
これらの人にとっては、そんなインターフェイスは必要ないのです。

 それに、もし少し大きいサイズにクレジットカードが変更されたら、それだけでお財布を買い直さなければならないかもしれません。
免許や定期が変わったとしても、同じです。
どれか一つが変わっただけで、お財布を丸ごと買い直さなければなりません。
お金を入れるところも何もかもが、役に立たなくなってしまうのです。

 これは、一つのインターフェイスの変更が、他のインターフェイスに影響してしまった例です。
道具というのは、長い目で見ると、多機能なものより単機能なものの方がいいということですね。

 この例のカードやお金は、持ち歩きやすくするために、お財布を利用します。
お財布を利用する立場ですので、カードはお財布のクライアントであるといえます。
お財布は、収納するという機能を提供する、サーバです。

 ここで、冒頭の原則の内容を思い出して下さい。
クライアントに、クライアントが依存しないメソッドへの依存性を強制してはならない
これを今回の例に当てはめると、
「(お財布は)カードやお金に、それぞれのカードやお金自身のもの以外の入れ場所に対して依存させてはならない」
ということになります。

 この場合の「依存している」とはどういうことかというと、他の入れ場所が使えなくなったときに、自分の入れ場所まで使えなくなるという影響を受けることです。

 高機能お財布のなかには、それぞれの入れ場所が、べつべつに取り外せるようになっているものもありますよね。
そういうものは、使えなくなったところだけを取り外して、お財布自体は使い続けることができますね。
これなら、ちゃんとインターフェイスが分離されているといえます。

 このように、インターフェイスはそれを使うクライアントによって、分離されているべきなのです。
これが、インターフェイス分離の原則です。

原則の関連

 ちょっと振り返ってみてください。
あなたが上司に対する話し方を変えなかればならなかったのは、上司が変わったことが原因でした。
また、お財布が使えなくなったのは、カードが変わったせいでした。
つまり、ここでインターフェイスは、あなたやお財布というサーバ側の都合ではなく、上司やカードというクライアント側の都合によって変更されたのです。
インターフェイスは、サーバー側ではなく、クライアント側の都合によって変更されることがよくあります。

 このことを、依存関係逆転の法則と関連づけて考えてみて下さい。
依存関係逆転の法則のお話に出てきた上位のモジュールは、たいてい利用する側、つまりクライアントです。
下位のモジュールは、たいてい利用される側、つまりサーバになります。

 このように、原則もパターンに似て、有機的に結びついているのです。

ソフトウェア開発者の方のための追記

 インターフェイスの肥大化の問題は、プログラムでは継承階層のあり方にも影響します。
継承階層の上位にあるクラスが、一部のクライアントしか利用しないようなメソッドを持っていると、全てのサブクラスがそれを実装しなければならなくなります。
あるサブクラスではそのメソッドを実際に使用するでしょうが、他のサブクラスでは、それは使わないメソッドになってしまうでしょう。
そういったサブクラスでは、そのメソッドをサポートしないというような例外を投げるか、何もしないでリターンすることになります。
これはインターフェイスの退化であり、潜在的にリスコフの置換原則に違反することになります。

 こうなっていると、実際にメソッドを使用しているサブクラスの変更によって、メソッドのインターフェイスが変わってしまった場合に大変なことになります。
上位クラスに変更が及ぶのはもちろん、全てのサブクラスにまで、変更が及んでしまうのです。
全てのクラスが、そのメソッドを実装しているのですから。
全く無関係なクラスに影響が波及していく、悪夢のような状況です。


 ところで、インターフェイスがクライアントごとに分離されていなければならないということは、それぞれのインターフェイスの仕様は、クライアントの都合によって決まるということを示唆しています。
これも、依存関係逆転の法則と矛盾しない方針ですね。


 さて、インターフェイスを分離して、サーバがこれを実装するという方針を実現するには、主に2つの方法が考えられます。
ひとつは、アダプタパターンを利用した、委譲による実現方法です。
もうひとつは、多重継承による実現方法です。
アダプタパターンについては、デザインパターンのカテゴリで、おいおいお話ししたいと思います。

 委譲による方法では、アダプタオブジェクトのためのクラスを大量に作成しなければならないかもしれません。
また、いちいちアダプタオブジェクトを生成しなければならないことや、委譲によるオーバーヘッドが問題になることがあるかもしれません。
そういったことが問題になる場合は、多重継承の戦略を採用することになるでしょう。

 多重継承では、アダプタオブジェクトが必要ない分、クラス数を抑えることができ、設計もよりスマートになります。
単一継承の言語を使用するなら、単にインターフェイスをインプリメントすることで実現することができます。

オススメ

 オブジェクト指向の原則については、アジャイルソフトウェア開発の奥義で詳しく解説されています。
 「問題のあるサンプル設計を元に、どこに問題があるのかが説明された上で、改善の方針と、改善結果の設計を示す」という流れで、具体的に、わかりやすく解説されています。
また、その設計に沿ったサンプルコードも、随所で示されています。

 この他、アジャイル開発の本質とプラクティスや、デザインパターンの適用方法なども、非常に実践的に解説されています。

 後半では、実際のシステムを開発するケーススタディに沿って、さらに具体的な実践例が示されます。

 きちんと本質をおさえた上で、その実践まで具体的に示されている、素晴らしい本です。
posted by craftsman at 06:21 | 東京 🌁 | Comment(0) | TrackBack(0) | 原則
この記事へのコメント
コメントを書く
お名前:

メールアドレス:

ホームページアドレス:

コメント: [必須入力]

認証コード: [必須入力]


※画像の中の文字を半角で入力してください。

この記事へのトラックバック
×

この広告は1年以上新しい記事の投稿がないブログに表示されております。