こんにちは、赤坂です。
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