ひがやすを技術ブログ

電通国際情報サービスのプログラマ

Statelessの意味

Stateless BusinessLogicにおけるStatelessの意味が分かりづらいところがあるようなので補足します。
ここでいっている「Stateless」とは、

オブジェクトのメソッドを呼び出す前後で、オブジェクトの状態が変わらない。

ということで、「オブジェクトの状態が変わらない」とは、

オブジェクトのインスタンス変数(もちろんstatic変数も)を更新しない。

という意味で使っています。
ある業務ロジックコンポーネントがあって、メソッドMa、メソッドMbをもつとします。Ma、Mbとも引数としてクライアントが入力した状態Sを受け取るとします。
Statelessな場合は、Ma、Mbに依存関係はありません、と以前書いたのですが、実は間違ってますね。m(_ _)mここでいっている依存関係とは、呼び出し順序の依存関係です。
状態Sが更新されない場合は、確かにMa、Mbには依存関係はありません。しかし、MaでSが更新され、MbがMaで更新されたことをあてにしている場合、MbはMaに依存しているということになります。
次に、状態Sをコンポーネントの状態として持つ、Statefulな場合を考えてみます。Ma、Mbの依存関係については、Statelessの場合と同様です。ただし、状態Sを引数ではなく、インスタンス変数として持っているため、状態Sを作り出したクライアント専用になります。なぜなら、Thread Safeの問題が出てくるためです。
それに対し、Statelessなら、引数として状態Sを受け取るので、1つのコンポーネントで、多くのクライアントを同時に処理することができます。
Statefulでやる場合、状態Sを持ったJavaBeansをnewして作成し使うことになるでしょう。そうすると、クライアントは、インターフェースではなく、実装クラスに依存することになります。それを避けるために、すべての状態ごとにFactoryクラスを用意するのは、面倒でコストがかかります。
Statelessでやる場合は、実装クラスの生成やDIは、DIContainerがすべて面倒を見てくれます。
こう考えていくと、プレゼンテーション層から最初に呼び出されるクラスは、Statelessにすべきだと思います。その後は、

  • 状態をドメインオブジェクトに変換して、ドメインオブジェクトのメソッドを呼び出すドメインモデルと
  • 状態をDTOとして、業務ロジック層でそのまま処理するリッチな業務ロジックモデルの

2パターンに分かれると思います。
リッチな業務ロジックモデルをTransactionScriptと呼ぶのはどうも違和感あります。(^^;


追記:これは、「データと振る舞いは常に分離した方が良い」ということではありません。業務ロジックは、データよりは、業務機能の方においた方が良いと思うということです。複数の業務機能で、同じデータを使うことは良くありますが、ロジックは、業務機能ごとに異なる場合が多いでしょう。