Service Layer
Defines an application’s boundary with a layer of services that establishes a set of available operations and coordinates the application’s response in each operation.
-
エンタープライズアプリケーションのインタフェースはクライアントにより様々
- Data Loaders
- UIs(人間がポチポチしたりするやつ)
- Integration Gateways(連携するやつ)
-
インタフェース越しに行われるデータ操作やロジックは共通
-
複雑だったりする
- トランザクション
- 複数のレスポンスを組み合わせる
-
- 共通化しないとコード重複まみれになる
-
Service Layer
- アプリケーション境界を定める
- クライアント視点で、利用可能な操作を定義する
- アプリケーションのビジネスロジックをカプセル化する
- (ビジネス)トランザクションを制御する
- 複数のレスポンスを組み合わせて何か処理を行ったりする
How It Works
- 実装の仕方はいろいろ
- だがその前に背景
Kinds of “Business Logic”
-
「Business Logic」は2つに分解できる。分けよう
-
Domain Logic
- 収益認識の計算方法ストラテジとか
-
アプリケーションをまたいで使えるやつ
- 【所感】「消費税率10%」とかはここか
- Domain ModelやTransaction Script等が表現するやつ
-
Application Logic
- Workflow Logicと言ったほうがわかりやすいかも
- アプリケーション固有のロジック
- Service Layerのオブジェクトが表現すべきやつ
-
-
Domain Logicにアプリケーション固有のロジックも持たせてしまうと…
- 再利用性を損なう
-
アプリケーションロジックを再実装するのが大変になる
- 【補】既にアプリケーションロジックを持っているクラスに、別のアプリケーションロジックを追加するのが困難、と言う意味合いかな
Implementation Variations
-
domain facade approach
-
サービス層なるべく薄く
- ビジネスロジック一切実装しない
- Domain Modelがすべてのビジネスロジックを実装する
-
-
operation script approach
- 厚いサービス層
- アプリケーションロジックを実装する
- ドメインロジックはDomain Modelに委譲する
-
基底のServiceクラスをもうけてLayer Supertypeにするとよい
-
抽象化する
- 責務
- 共通のふるまい
-
To Remote or Not to Remote
- リモートコール時はDTOでコール数減らす
- サービス層にDTO対応のcoarse-grainedなインタフェースをもたせる
-
大変だぞ
- O/Rマッピングの次くらいに大変
- そもそも、オブジェクトの分散配置は本当に必要ですか(やらないに越したことはない)
- ローカル用のfine-grainedなインタフェースをまず持たせよ
- リモートコールが必要になったそのときRemote Facadeを追加しろ
Identifying Services and Operations
- サービス層の境界の話
-
クライアントの必要(ユースケース)に応じて生やすことになる
- 典型:UI
-
多くのユースケースは、ただのドメインオブジェクトのCRUD。退屈
-
サービス層の操作とCRUDユースケースは大抵1対1対応
- 【補】それで全部ということ
-
-
退屈じゃないことも
- バリデーション
-
CUD時の通知
- 使ってる人
- 連携している外接系
- さらに原子性が求められたり
-
サービス層をどう抽象化するかは、「経験からくる勘」に頼る部分が大きい
-
<アプリケーション名>Service
- 1つのサービスに抽象化
- 小さいアプリケーションならこれでいい
-
<サブシステム名>Serivce
- 大きいアプリケーションは、サブシステムに分ける
-
<代表的なDomain Modle名>Service
- ConctractsService とか
-
<アプリケーションの振る舞いのテーマ>Service
- RecognitionService とか
-
Java Implementation
-
実装の選択肢
- POJO
- stateless session bean
- テスト容易性(POJO有利)と、トランザクション制御(stateless session bean有利)とのトレードオフ
-
著者おすすめ
-
サービス層はstateless session beans
- ローカルインタフェース
- トランザクション制御のしくみがある(container-managed transaction)
-
ドメイン層はPOJO
- テストしやすい
-
-
Session FacadeパターンとService Layerとの違い
- 意図が異なる
-
Service Layer
-
ビジネスロジックを2分してドメインロジックをはじき出すためのやつ
- コード多重化回避
- 再利用性向上
-
-
Session Facade
- パフォーマンス問題を解決するためのヤツ
- リモートコールを減らす
When To Use It
-
いつ使う
- クライアントが複数種類ある(今後ありそう)
-
複数のレスポンスをまとめて何かする
-
原子性が求められたりする
- ビジネストランザクション
-
- 複数のトランザクショナルリソースが絡む
-
逆にいつ使わない
- クライアントが一種類だけ
- 複数のトランザクショナルリソース絡まない
-
使わないとき
-
Page Controllerが同様の仕事をする
- トランザクション制御
- レスポンスするデータの取得
-
Further Reading
-
Service Layerのインスピレーション元
- Alistair Cockburn’s application boundary pattern [Cockburn PloP]
-
リモートファサード
- vein [Alpert, et al.]
-
セッションファサード
- Alur et al.
- Marinescu
-
Service Layerまわりの責務の話
- Cockburn UC
-
Fusion Methodology
- OOAD: オブジェクト指向分析設計の中でも流行っていたやつ?
- system operations [Coleman et al.]
Example: Revenue Recognition (Java)
- コード略(pp.138-141)
- 基底のサービスクラスをつくる(Layer SuperType)
-
外接系のインタフェースを用意し依存する(
<<uses>>
)- Gateway
-
EJBを使う場合: “Business Interface” Idiom を適用
- 【所感】このへん読み違えてるかも。クラス図がなんかおかしい
- 【補】Bridge Patternな感じ
- Layer SuperTypeでEJBのインタフェースを実装する(
ApplicationServiceBeanImpl
) - それを継承して各サービスを実装する(
RecognitionServiceBeanImpl
) - EJBを使用していることを隠蔽する(
RecognitionService
インタフェースを実装する)
-
スクリプティングとドメインオブジェクト両方使うことになるのがキモ
-
両方の良い所どり
- ドメインオブジェクトで複雑なドメインロジックを表現
- スクリプトとContainer Managedのしくみでトランザクション処理
-
-
Observer Patternを使ってはどうか?
- 【補】Gatewayからの連絡用か
-
サービス層をステートレスにできなくなるのでよくない
- マルチスレッド時に並列性の問題が生ずる
-
下の層にアプリケーションロジック持たせちゃダメなの?
-
2つの理由につき上の層に持たせるの推奨
- 下の層(Domain層)の再利用性を高める
- アプリケーションロジックを単離することで、変更しやすくなる
-
英語
-
commingle
- Mix; blend.