« [プログラム設計事始] メソッドの外部設計(1) | トップページ | ハイブリッド車が、 新車販売台数のトップを競い合う時代の到来 »

2009年5月20日 (水)

[プログラム設計事始] 外部設計と内部設計の狭間

外部設計と概略設計」 で、 外部⇔内部 と 概略⇔詳細 とは直交する概念だということを示しました。  同じ図をもういちど掲載しておきます。

Program_design02_01

ここで、 概略と詳細の間にはいくらでも中間段階がありえるということは、 おわかりいただけると思います。 複雑なシステムでは、 全体の概略を示し、 それを分割したサブシステムとして表し、 それぞれをまた分割したサブ・サブシステムとして定義し… と、 概略から詳細へ何段階かに渡って設計していかなければ、 人間のアタマでは把握しきれないでしょう。
では、 外部設計と内部設計は? きれいに二分されるものでしょうか?

外部設計は、 それを使うモノに対しての 「公約」 になります。
システムの外部設計は、 顧客・ユーザーに対しての 「公約」 ですから、 勝手に変更することは許されません。 フレームワークの外部設計は、 フレームワークを利用する開発者 (あるいはサブシステム) に対する 「公約」 になりますから、 やはり勝手に変更できません。 メソッドの外部設計は、 そのメソッドを使う開発者 (あるいはメソッド) に対する …以下同文。

それに対して、 内部設計は、 外部設計に影響が及ばない限りにおいて、 好き勝手に設計することができます。

そういう意味では、 「公約」 と 「お家の事情」 が綺麗に分離されていることが理想でしょう。

しかし、 現実はそう上手くいかないものです。
「プログラム設計」 ( 「プログラムの本質と、 インターフェース部分を分けるということ」 参照 ) においては、 次のような例を考えつきました。
(1) 内部設計を考慮して外部設計をしたほうが良いことがある ( 内部設計の外部設計への干渉 )
(2) 外部設計と内部設計に同じ部分がある。 ( 外部設計と内部設計の重複 )

 

◆ 内部設計の外部設計への干渉

よく言われる、 「言語やフレームワークを知らない SE が作った仕様は、 実装できやしねぇ~ (--; 」 という話です。 内部設計 ( 実装含む ) を考慮して外部設計やってよ、 というボヤキですね。

メソッドの外部設計(1)」 で最初に示した設計では、 null の引数に対して、  出力を (NullReferenceException) としました。 なぜそうしたかというと、 わざわざそのために何か実装をしなくても、 NullReferenceException が発生するからです。
二番目に示した設計では、 null に対して null を返すこととしました。 その場合は、 実装するときに、 例えば if 文で null かどうかを判定する部分を追加しなければなりません。
この例では if 文ひとつの増加ですが、 実際のプロジェクトでは、 外部設計のちょっとした違いで、 実装の複雑さが大きく変わってしまう可能性があると思います。

このことは、 外部設計を完了させる前に、 内部設計を検討して、 外部設計を見直してみるべきである、 ということを示唆します。

別の例を挙げます。
メソッド A() が、 メソッド B() を呼び出すとします。 そのことを、 メソッド A() の外部設計に含めなければならない場合があります。 ( 別途、 書きます )
しかし、 メソッド B() を呼ぶ必要があるということ、 また、 ちゃんと呼び出せるということ ( 例えば違うアセンブリに入っていて、 そこを参照できなかったら、 呼び出せません ) を知るためには、 メソッド A() の内部設計を理解している必要があります。

このことは、 外部設計を検討しているときに、 内部設計も検討する必要がある場合もある、 ということを意味します。

 

◆ 外部設計と内部設計の重複

設計の記述は、 重複しないことが理想です。 同じことが複数箇所に書かれていると、 メンテ漏れが発生しやすくなりますから。 外部設計と内部設計も、 重複しないことが理想でしょう。
※ この見方からすると、 概略設計⇔詳細設計 の間は少ないほうが良いことになります。 しかし、 必要以上に中間レベルを飛ばしてしまうと、 こんどは把握しきれなくなります。 あるいは、 重複を避けようとして別文書への参照だらけにしてしまっても、 やっぱり把握しにくくなるでしょう。  けっきょくはバランスを取るのが難しい、 ということですね。

クラス設計は、 外部設計と内部設計の重複がわりと多くなると思います。 次に挙げる例は、 外から見える部分しか存在しないため外部設計と内部設計が完全に重複していて、 いわば内部設計が必要無い、 とも言える場合です。

パブリックメンバーしか持たないクラスを考えてみましょう。
クラス単体の外部設計では、 外から見える状態と振る舞いを定義します。 パブリックメンバーとして整数 x と y だけを持った、 Point クラスを考えてみます。

外部設計をクラス図で表現すると、 こうなります。

Point
+ x : int
+ y : int

内部設計を、 実際のコードで示すと、 こうですね。

class Point{
 public int x;
 public int y;
}

表現形態は違いますが、 表現していることは同じです。

  

以上、 2つのパターンを挙げてみましたが、 他にもきっとあると思います。
外部設計と内部設計は、 理想としてはきれいに分離していて欲しいと思うものの、 そうはいかないこともある。 言い換えれば、 外部設計と内部設計の中間もあるであろう、 ということでした。

|

« [プログラム設計事始] メソッドの外部設計(1) | トップページ | ハイブリッド車が、 新車販売台数のトップを競い合う時代の到来 »

プログラミング」カテゴリの記事

コメント

コメントを書く



(ウェブ上には掲載しません)


コメントは記事投稿者が公開するまで表示されません。



トラックバック

この記事のトラックバックURL:
http://app.cocolog-nifty.com/t/trackback/209349/45073805

この記事へのトラックバック一覧です: [プログラム設計事始] 外部設計と内部設計の狭間:

» biac の それさえもおそらくは幸せな日々@nifty: プログラミング [ravipendigg]
Thank you for submitting this cool story - Trackback from ravipendigg [続きを読む]

受信: 2009年5月21日 (木) 11時07分

« [プログラム設計事始] メソッドの外部設計(1) | トップページ | ハイブリッド車が、 新車販売台数のトップを競い合う時代の到来 »