Bob Martinは作業ユニットがスレッドに対してそれぞれ一つ一つの関係を築いているという仮説(source)に潜在する問題に関して、ある記事を書いた。
ThreadLocal変数は与えられたスレッドをデータと関連させるのにおいて驚くほど便利なのだ。まさにHibernateのようなフレームワークはセッション情報を保つのにこの利点を活用している。しかしながらそれはスレッドが作業ユニットに同等であるという仮説に基づいているのだ。この仮説は間違っているのである。
ThreadLocalはJava用語であるが、その構造はマルチスレッド環境と共通点がある。Bob氏は下記のように述べている。
13年前、一番初めの本に取り掛かっていた時、Jim Coplienと私はスレッドとオブジェクトの性質において討論したことがあった。彼はそれ以来私の頭に焼き付いている明瞭な発言をした。彼はこう言った。”オブジェクトは機能の抽象概念である。スレッドはスケジュールの抽象概念である。”
作業ユニットのデータを一つのスレッドにマッピングするのは、今日では一般的なパターンとなっている。例えそのアプローチが大変な時間を費やすものであっても、誤った抽象概念だったとしても、フレームワークに良く見受けられるパターンなのである。
タスクが異なる部分において異なるプライオリティを所有しているのは一般的ではない。そしてタスクがシングルスレッドでなければならないという規則も無いのだ。Bob氏は作業ユニットが、入力されるデータに基づいた比較的長時間の命令を実行している間に、作業ユニットが外部サービスとの応答性のコミュニ ケーションを必要とするかもしれないことでそれを実証している。問題は一般的に二つのスレッドを使用することで解決されるということだ。彼は疑問を投げかけている。
作業ユニットに関連した変数はどこにあるのだろうか?それぞれのタスク部分が別々のスレッドで動作するので、スレッドをローカルに保つことはできないのだ。 そして一つ以上のスレッドがあるので静的な変数に保つこともできない。その答えはスタック上の"function argument"としてスレッド間で受け回される必要があるのだ。そしてキュー上で構造されたデータの中に保存されなければならない。
TapsaKoo氏は以前に同じような状況に直面したことがある。WinForms内においてドメイン駆動で作業しようとした時、セッション特有データを保存する場所を見つけるのが困難であったことを述べている。(source)
もしアプリケーションが一度に開いているフォームが一つしかなければ、CallContextの中にセッションオブジェクトをセーブすることができた。もしもアプリケーションが一度に複数の開いたフォームがあり、それぞれがセッションクラス別々のインスタンスを所有させたくなったらどうなるだろうか。CallContextは問題外である。全てのスレッド特有の代替策もそうである。そうなると何が残されているだろうか。何も残されていないのだろうか?この問題に関して注目し始めたのは私が初めてではない。解決策があるはずなのだが未だ見つかっていない。本当にセッションオブジェクトをそれを必要とする可能性のあるオブジェクトインスタンスに注入しないといけないのだろうか。それともドメインクラスからたくさんの振る舞いをサービスにリファクタリングし、セッションオブジェクトをそれに 注入するべきなのだろうか。私はクラスを単なるコンテナ以上として扱いたいので、このアプローチがあまり好きではない。
Bobおじさんの記事を読んで、Tapsakooはこの問題に対する簡単な解決策はないことに同意した。(source)
スレッドが1つ、または10あったとしても関係ない。問題はいつも一緒なのだ。作業ユニットかセッションステートにはスレッドに依存しない場所があるべきだ。作業ユニットが直接一つのシングルスレッドに関連していると考えるのはとても危険なのである。その考え方は他のアーキテクチャにおける選択の幅をひどく狭めてしまうのだ。
Bob氏は何かが欠けているという結論を下した。
便利であるのだがスレッドローカル変数はスケジュールから機能を分離する課題を混同させる。そしてそれはファンクションとスケジュールを一緒にしたいという願望を持たせさせるのだ。ファンクションの通信とスケジュールが軟弱で偶然的であるためこれはあまり効率的ではないのだ。
私たちが本当に望むのはローカル作業ユニット変数を作ることなのである。
原文はこちらです:http://www.infoq.com/news/2007/09/confusing_uow_with_threads