どのクラスに処理を記述すべきか?

1つユースケースに閉じていることは、すべてActionに記述し、複数のユースケースで使われるものをLogicに分割するのがシンプルでわかりやすいのではないかと、そう思ったわけです。


<<中略>>


追記2:コメントへの回答ですが、ユーティリティは、staticメソッドで構成されるやつは、utilのパッケージ。ActionにDIするやつは、logicパッケージでいいと思います。どっちでもないユーティリティもutilパッケージですね。


Entityについては、SAStrutsのドキュメントにもこのblogでも書いていますが、1つのEntityに閉じたロジックならEntityに記述するということでいいと思います。複数のユースケースで使うからこそ、Entityに書く意味がありますね。個別のユースケースでしか使わないなら、Actionに書いたほうがいいと思います。

上記のひがさんのエントリーを元に「どのクラスに処理を記述すべきか?」の
方針を図示して整理してみました。


というのも、「どのクラスに処理を記述すべきか?」を考えるにあたって
いくつかの判断が必要ですが、判断対象の順序次第でえらく混乱を招くことを実感したため、
判断の順番を考慮したフローチャートベースのシンプルで明確な方針(ルール)の必要性を感じたからです。
(実際に、最初に「複数のAction(ユースケース)で使われるか?」という判断から検討した結果、結構混乱しました。)


追記:
当初は『複数種類のEntityにまたがっているロジックは、制御ロジックととらえて、Logicに持たせるのが基準が明快なのでわかりやすいのではないでしょうか。』ということでした。しかし、詳細は下記のエントリーを見ていただくとして、今は『複数種類のエンティティにまたがるロジックも、エンティティに書く』と考えに至っています。そんな訳で、上記のフローチャートは一旦保留。


 複数種類のエンティティを扱うロジックをどこに書くのか
 http://d.hatena.ne.jp/higayasuo/20080208#1202449061


こういった方針をきちんと示さずにいると、
「いびつに肥大化したユーティリィティ」や
「確信犯的なコピ&ペーストの山」に
プロジェクトのソースコードが汚染されてしまうので、
DRY原則を実践する上でも、とても大切なことだと認識しています。


また、ここで挙げた方針が適切かどうかは別として、
 「1つの方針をメンバー間で共有して深くコンセンサスを得たうえで」、
 「方針に照らし合わせて各個別の事象がどう有るべきかをメンバーと対話しながら検討する」
というプロセスが非常に大事だと思いました。
(あと、経験や先入観がルールベースの思考を妨げる要因になることも改めて実感できた。)


まあ、結論は「判断の順序重要」ということで。

どのクラスに処理を記述すべきか? 〜 Part2

SAStrutsアーキテクチャにおいて、それぞれの処理をどのクラスに
記述するのが良いかの検討を引き続き行う。


下図はブラッシュアップした現時点での判断チャート。
順を追って説明してみる。


ユーティリィティ的な処理か?

何を持ってユーティリィティ的な処理とみなすかは以外に難しい。


しかし、どのクラスに記述すべきかの見極め以前に、そもそも、
そのソースコードを書く必要があるかを疑ったほうがいい。


Apache CommonsやSeasar2のutilパッケージなど第三者
作成したユーティリィティクラスでかなりの代替が利くはず。
プログラマ全員がプロジェクトの最初の段階で、
役立つ3rdパーティのユーティリィティ情報を共有しておくべし。


あとは、ユーティリィティ的な処理かどうかの見極めに
自信がない人は、センスのよさそうに相談するのが良い。

画面周りの処理か?

画面周りのロジックの代表的なものは、
条件分岐によって画面遷移や画面部品等の振る舞いが変わるものと
とらえればイメージしやすいのではなかろうか。


さらに、この条件分岐のためのフラグ値を作成するための
メソッドまで落とし込めば分かり易いと思う。


注意すべきは、条件分岐の入力要素にEntityが絡むケース。
画面側とDB側の両方のクラスが絡むだけに、
『画面周りの処理である』と言い切るのに躊躇してしまいがち。
これについては、メソッドの引数にEntityそのものを渡すのではなく、
Entity内部のプロパティを渡すようにすることで、モヤモヤ感が晴れるはず。

複数のActionをまたがないか?

この判断は、アプリケーションの機能全体を見渡していないと
複数のActionをまたぐかどうかを判断しずらいので、
規模が大きいと結構難しいかもしれない。


これについては、アーキテクチャや個人の資質で対応するのは
限界があるとおもうので、マネジメントレベルでの
対策も検討しなければならないと思う。

特定のEntityへの処理記述に無理を感じるか?

これも難しい。コウモリ問題や同じクラスだが複数の別インスタンス
一括して扱うロジックなどを考慮すると、ロジックはEntityだけに
記述すれば良いものではないと思おう。


これはセンスと割り切らずに、いろいろな事例を検討して
明確な見極めポイントをもう少し模索する必要があるなぁ。