1.5階層のAction-Service-Logicパターン

趣旨とあんまり関係ないですが、Service・Logicをとりまぜた3階層にするならば、エンティティによったものをService、アクションによったものはLogicと呼んだ方が、フレームワーク側の呼び方との親和性は高いように思います。


ちなみに、今はこんな感じの設計はどうかと思っています。


Serviceクラス:エンティティと対につくる。ドメインモデル的な考え方がプロジェクト内でついていけないならばいっそのこと導入しない。


Logicクラス
ユースケースを跨がる画面まわりの制御処理や、ユースケースをまたがるビジネスロジック特有の処理を書く。いわゆる、サブシステム間共通関数のイメージ。たとえば複数ユースケースであるケースでは沢山の表にインサートするが、あるケースではアップデートのみするようなものを使う。
・ただし、Serviceクラス的設計が難しい場合には、画面制御的なクラス


Serviceクラスはフレームワークチュートリアルや今後出版される本などでも、ENTITYと連関した紹介がされるでしょうから、学習コストを考えると、アクション内の共通処理的なものの名前はLogicなど別の名称のほうがよいのではと思いはじめています。

kataoka_ayumu さん、ブログ上では初めまして(笑)。
kataoka_ayumu さんの考えているアーキテクチャを図示するとこんなイメージでしょうか?


図1: 2階層のAction-Service-Logicパターン


「Logicクラスの役割」や「フレームワーク側の呼び方との親和性」などは私も同意です。
もし、想定しているアーキテクチャが上の図と同じであれば、『ユースケース固有の要求も全てエンティティ単位のService経由で処理する点』については、意見が分かれるところだと思うので、深く検討してみる価値はあると思います。


私の考えている具体的な懸念点は次のとおりです。

  • エンティティ粒度のモジュールにふさわしくない特定のユースケースや特定の画面に依存した名前のメソッドが散在してしまう。(ユースケースに依存しない名前を振る方法も考えられるが、名が体を表さないメソッドを量産してしまうので混乱が生じる。)
    • 特定のユースケース名のメソッドがServiceクラスに配置されるようになると、ロジックの重複が発生しやすくなる。(重複対策としてエンティティ単位のServiceを導入したはずなのに。。。)
    • 責務を超えたメソッドが配置されるため、特定のサービスが肥大化する。(マッチング系アプリだとこの傾向が顕著に現れるはず。)しかも、多人数で特定のファイルを編集しなければならないので作業効率が悪化する。


上記の問題に対処するために、以下のアーキテクチャはいかがでしょうか。


図2: 1.5階層のAction-Service-Logicパターン


先ほどのアーキテクチャとの違いは、ActionからServiceを経由せずに直接JdbcManagerを経由したデータアクセスを想定している点です。ちょっとした違いですが、先ほどの問題点は全て解消されるはずです。


デメリットとその対処方にも触れておきます。
ユースケース固有の要求は、Action単独で処理するやり方とServiceを利用して処理するやり方の2通りになってしまうことで、選択肢が増えてしまうのがデメリットです。ただ、このデメリットもActionクラスにテストコードを用意しておけば、リファクタリングは容易なので、「完璧な使い分け方針決めなければ」と気構えずに、最初にゆるい方針を決めて、プロジェクト途中で方針を明確化してゆくやり方が割と現実的な感じがします。

また、Actionにデータアクセス処理を配置すると、データアクセス処理部分をテストやメンテナンス性を考慮して、メソッド抽出したくなるかも知れません。この場合、メソッドの入力要素がメソッド引数とフィールドに分散してしまうのでメソッドのインターフェースが曖昧になりがちなデメリットが想定されます。これについては、Action内でテストすると決めたメソッド抽出したメソッドに対しては、フィールドアクセスは使わずに、全てメソッド引数を使うようにすれば、メソッドのインターフェースは自然と明確になると思います。


追記:
このアーキテクチャは、画面項目プロパティをアクションフォームに配置する方法を想定しています。Actionクラスのデータアクセス処理するメソッドへの引数は、アクションフォームをそのまま渡す、もしくは、アクションフォーム内で定義した内部クラスを渡すことを想定しています。


Action-Service-Logic の3つを使うにもかかわらず、階層数が ではなく1〜2というのがオモローですね。今後、名前がないと対話しずらくなるので、ひとまず『1.5階層のAction-Service-Logicパターン』命名しておきますね。