PoEAA Ch9 Transaction Script

PoEAAデザインパターン勉強メモ

出典: 


Transaction Script

Organizes business logic by procedures where each procedure handles a single request from the presentation.

  • ビジネスロジックの複雑性は様々

    • DBの情報を表示するだけ
    • 幾重ものバリデーションと計算
  • Transaction Scriptでは、このロジックを(基本的には)1つの手続きにまとめる

    • 共通化のためにサブルーチン切ったりもするけど
  • DB直呼びor薄いラッパ層を通して呼ぶ
  • トランザクションにつき1スクリプトが対応

How It Works

  • ドメインロジックはトランザクション単位

    • 例:ホテルの予約 Book Hotel Room プロシージャ

      1. 部屋の空き確認
      2. 料金計算
      3. DB更新
  • ドメインロジックが複雑でない限り、そう難しいことはない
  • 利点

    • 他のトランザクションについて考える必要がない

      • 【補】システムトランザクションとビジネストランザクションが一致するから
  • ながれ

    1. 入力
    2. DB問い合わせ
    3. 難読化(PWとか)
    4. DB永続化
  • Transaction Scriptsをどこに置く
  • レイヤーの切り方しだい

    • server page
    • CGI script
    • 分散セッションオブジェクト
  • 可能な限り分離せよ

    • 少なくとも、別のサブルーチンに分けろ
    • プレゼンテーションやデータソースとは別クラスだとなお良い
  • Transaction Scriptからプレゼンテーションを呼ぶな
  • さすれば下記が容易になる

    • コードの変更
    • テスト
  • Transaction Scriptをクラスに配置するにあたり2つやり方がある

    • 1つのクラスにいくつかのスクリプト
    • 1クラス1スクリプト(Command Pattern)

      • 柔軟
      • ドメイン層にTransaction Scriptを使うほどシンプルなドメインロジックで必要になることはまずない
  • グローバル関数はやめたほうがいい

    • マルチスレッドにすると死ぬ
    • クラスに生やしたほうが、インスタンシエートしてメモリ上のデータを分離しやすいので良い
  • Transaction Scriptたる所以 … 殆どの場合、1スクリプト1DBトランザクション

When to Use It

  • Transaction Scriptの長所: 単純であること
  • ビジネスロジックが複雑化すると、「よく設計された状態」を保つのが難しくなってゆく

    • コピペ
  • 共通部分を抽出することでコピペ問題は回避できる
  • 複雑ならDomain Model

    • 柔軟
    • 可読性増す
    • コード多重化も減らせる
  • Transaction Script からDomain Modelに切り替えべきポイントはどこ

    • 定量化は困難
    • どちらかに慣れ親しんでいればなおのこと
  • Transaction ScriptからDomain Modelにリファクタリングするのは、必要以上の困難を伴う

    • 【補】最初からDomain Modelで作るよりも大変ということ
  • のでDomain Modelに切り替えるのは早いほうがよい
  • (著者のように)OOP大好きおじさんになったとしても、Transaction Scriptを完全には捨て去るな

    • 単純な問題は単純な解法ですばやく解決できる

The Revenue Recognition Problem

  • ドメインロジックのパターンを語る上での例題
  • 収益認識

    • 生産基準とか販売基準とか回収基準とか
  • 普通の商品売買なら単純
  • 前払金とかが絡むと自体は複雑になる

    • 月割の計算とか
    • 割賦とか
  • 3つのソフトウェア製品を売る例を考える

    • ワープロ

      • 即金
    • スプレッドシート

      • 今日1/3
      • 60日後1/3
      • 90日後1/3
    • DB

      • 今日1/3
      • 30日後1/3
      • 60日後1/3
  • テキトウだけど現実もこんなもんだ

Example: Revenue Recognition (Java)

RecognitionService -> Gateway
  • コード省略

    • pp.113-115
    • Transaction Script

      • RecognitionServiceクラスのメソッドとして複数生えている
    • データソース層

      • Table Data Gatewayを採用したらしい
  • 計算が単純ならスクリプトとSQLはおよそ1対1対応
  • 金絡みの計算はMoneyを使え

    • 通貨や丸めを考慮したユーザ定義型
    • 用意しないと容易に1円消えたりする
  • RecognitionServiceクラスは通常のクラス、もしくはJava session beanにしたりする
  • 後述のDomain Modelパターンに比べ、シンプル
  • ドメインロジックが複雑になったら手に負えなくなる

    • 収益認識ルールに、製品だけでなく日付も入ってきたら?

      • 4月15日以前の契約についてはXXXなるルールで、…
  • ので、著者のようなOOP大好きおじさんは最初からDomain Modelを採用する

英語

  • alleviate

    • Make (suffering, deficiency, or a problem) less severe.
  • retainer

    • A fee paid in advance to someone, especially a barrister, in order to secure their services for use when required.
  • delve

    • Reach inside a receptacle and search for something.