増9.「インターフェイスの使用」について
●今回の発端
以前、TDDについていろいろ言いましたが、なぜこのような概念が生まれたのか考えるようになりました。すこし、文書になるぐらいになったので、公開します。
●インターフェイスの問題点
インターフェイスは、かなり自由度があります。
- メソッドがいくつかある。呼び方についての制限の記述方法は(どんな言語でも)ない。
- メソッドのパラメータは大抵、普通の数字や文字列である。範囲指定された型はあい。(VB、.NETなどはString型が「NotInheritable」で、部分範囲型のようなものが作れない)
そのためか、まとわりついて離れない“不吉なにおい”があります。いかにも失敗しそうな自由度です。
●インターフェイスのさらなる問題点
メソッドのパラメータとしてのコード設計方法には、大きく2つのやり方があると思います。
- オブジェクトローカルのコード(内部の処理の都合のみで決めた)を用いる。オブジェクトの利用者が、呼ぶ度いちいちグローバルコード⇔ローカルコードの変換をする
- グローバルのコードを用いる
前者の場合、オブジェクトの設計の側からすると、
- コード1~コードm。以上。
ですが、後者の場合、
- コード1~コードn + 名状しがたいそれ以外。
となります。オブジェクトの設計者からすると、グローバルコードがなにとなにを取るかは、まったくわからず、ましてや将来にいたって分かるはずもありません。 さらに、その「名状しがたいそれ以外」は、
- オブジェクトの現状のロジックで対応可能。
- オブジェクトの現状のロジックで対応不能。
の2つに分かれます。
パラメタのコードの設計については、RDBの作法に端を発し、グローバルなコードを圧倒的に選ぶであろう今日、たまさか「現状のロジックで対応可能」な部分があるため、伝統的な「assert(実行中にテストし、不合格の場合無条件に異常終了する)」は適用しがたく、その代わりに「これこれはテストしましたが、名状しがたい部分はテストしてませんよ!」ということを、プログラム内に記述するTDDを思いついたのだと思いました。
●利用者の問題/保守担当者の問題/初心者の問題
そうはいっても、今まで実績のある入力のみでオブジェクトを使おうとしない、わがままな利用者が、TDDによるテストの記述を尊重してくれるとは到底思えません。
また、グローバルコードのコードの拡張について、通知を得られない立場の人間が、オブジェクトを保守しようとするのもあまりに無理があると思います。グローバルなコードの保守責任は、オブジェクトの利用者側とすべきです。
さらに、TDDに沿ってテストを書くと、仕様を意識することになり、初心者にとって有意義だという点も、それを「腹の底から理解しないと記述できない、別の言語である、自然言語」でなく、「同じ言語なので、うわべだけ理解していれば記述可能な、プログラム言語」で書くという事が、本当に教育的なのか心の底から疑問です。
●別案
どこでもグローバルなコードを使う事はあきらめ、
- 共通で使うオブジェクトでは、オブジェクトローカルのコードを使う。
- それを使う側は、自システムのどこかに(基底クラスやFriendクラス)「インターフェイスの使用」メソッド群を作る。そこで、グローバル⇔オブジェクトローカルコードの変換をする。
- オブジェクトを直に使う事は禁止、「インターフェイスの使用」を使う事で間接的に利用する。
というのはどうでしょうか? 「インターフェイス」だけを概念上の実体とするのでなく、「インターフェイスの使用」も実体とするのです。実体の数が増えるのですから、当然制御できる範囲も増え、“不吉なにおい”を押さえ込む助けになると思います。
まぁ、今回はこんなところです。
●コラムのコメント欄の方針
コメントに対し、当意即妙の回答を、それなりのタイミングでする自信がありません。
ですので、このコラムで、
・わたしは基本的にコメントに答えない
・コメントを書く人は、回答がない前提で議論を進めていただく
とさせていただきます。