Index: [Article Count Order] [Thread]

Date:  Sat, 16 Aug 2003 14:45:47 +0900
From:  Hidehiko AKASAKA <akasaka.h@....com>
Subject:  [XP-jp:04606] Re: 「 AnExtremeProgrammingEpisode 」の翻訳版を掲載しました
To:  extremeprogramming-jp@....jp
Message-Id:  <20030816134905.00A0.AKASAKA.H@....com>
In-Reply-To:  <20030816.121104.01365712.yamazaki@....jp>
References:  <20030814210915.92A5.ANC04864@....COM> <20030816.121104.01365712.yamazaki@....jp>
X-Mail-Count: 04606

こんにちは、赤坂です。

Susumu YAMAZAKI <yamazaki@....jp> san wrote:

> パターンカタログにまで整理した形には出来ないでしょうね。だから「不吉な
> 臭い」と書いたのですが。どちらにしても「誰でも」というわけにはいかない
> でしょう。経験を積んだ方がいいに決まっています。ただ、敷居を下げる役割
> は期待できるのではないでしょうか。

はい、敷居を下げることは重要だし、可能だと思います。

> 確かに整理する視点が難しく重要であると思います。ここで僕がヒントではな
> いかと感じているのは、ごうぎさんのおっしゃった
> 
> >  OOで設計した場合、1:9(あるいは2:8)の1(あるは2)の部分が、9(あるいは8)に
> > 影響を与えます
> 
> という言葉です。つまり、クラス間の依存関係を少し眺めれば、ある程度推測
> できるのではないかと思いつきました。確かに他からの依存が大きいクラスを
> 変更すると影響が大きいのは明らかです。

御意です。
依存関係はクラス間の結合度に直結しています。
クラス同士がどのように関係しているかが影響してきますよね。

> 一連の処理を分割した例でこのことを確かめてみますと、、、
> 
> 話を単純にするために処理を2つに分割することにします。クラスとしては
> Preprocessor と Postprocessor、中間結果を表す Intermediary、そして テ
> ストケース PreprocessorTest と PostprocessorTest があります。当然のこ
> とながら Intermediary 以外のクラスは Intermediary に依存します。特にテ
> ストケースは、記述の方法が Intermediary に強く依存し、他のクラスと比べ
> て記述量が増加する可能性が高いわけですから、Intermediary を変更すると、
> テストケースを大幅に変更しなければならないということが言えるわけです。
> 後から考えれば非常に当たり前な結論ですね。

そうですね。
以下のような前提で拝見します。
・Intermediaryはエンティティ(データ)クラス
・mainのProcessorはない(PostprocessorはmainのProcessor)

前半の処理(Preprocessor)と後半の処理(Postprocessor)は、それぞれ
ある入力から中間結果(Intermediary)を生成し、これを元にある出力を行う
ものと理解しました。
# 山崎さんの考えられてるものと合ってますでしょうか?

こういった場合には、中間結果が変更されると、それに(おそらく、get/setを
介しても、データ構造に)依存したクラス、およびテストも変更を余儀なくされ
てしまいますよね。
# よくあるケースですね。

こういうケースは良くありますし、これで悪くないと思いますが、
個人的にはエンティティ同士で(できれば相互に)変換出来る方が好みです。

以下、(特に良くなっているわけではありませんが)こんな感じですが…、
# 余計なInput,Outputもデータクラスとしてとりあえず出しておきます。

Input --> Intermediary --> Output

コードは以下みたいな感じで書きたいです。
  // Input ⇒ (Intermediary ⇒) Output
  Input input;
  Intermediary inter = Input.toIntermediary();
  Output output = Inter.toOutput()

テストはInput、Intermediary、Outputをまとめた単位で、

  // input ⇒ intermediary 変換のテスト(逆変換で検証).
  inter = input. toIntermediary();
  atctual = inter.backtoInput();
  assertEquals(inter, actual);

という感じで使いたいところです。
# それぞれのエンティティのテストでは変換以外のデータ要素だけにします。

理由は、機能クラスを必要以上に登場させたくないのです。
例えばユースケースのシーケンスの実行手順を司るようなControllerの場合、機
能クラスであっても全然構わないと思うのですが、(Preprocessor)と
(Postprocessor)については、データに依存した機能クラスになるからです。
# データに依存したクラスは上記の問題に嵌るからです。

データ間の依存はしかるべきと割り切ります。
データの変更があれば、依存する変換部分は当然修正されるものと考えます。

あと、Preprocessor, Postprocessorについては、必要があれば、

// Input ⇒ (Intermediary ⇒) Output
Input input;
Intermediary inter = Input.toIntermediary(preprocessor);
Output output = Inter.toOutput(postprocessor)

こんな感じになるのでしょうか。
# でもこうしてしまうと、変更時のテストの影響は大きそうですね。

# よく考えていないので、とんちんかんかも知れません。
# その時はご容赦くださいませ m(_._)m

あんまり、私自身、単体テストが上手くいってると感じたことはない(^^;;
のですが、もう少し良いアイディアがあれば教えて下さい m(_._)m

ではでは。
--
赤坂 英彦 (Hidehiko AKASAKA)
akasaka.h@....com