Context とは具体的に何なのか

簡単な実験を行うので、あれば飲み物とストローを用意してください。

みんなだいすき Bounded Context（境界付けられたコンテキスト）。
ですが、Context とは具体的に何なのでしょうか？

環境でしょうか？それは Environment です。
状態でしょうか？それは State です。
文脈でしょうか？難しい言葉を知ってますね！私は文脈とは具体的になんなのかのほうが難しくてわかりません！

実のところ Context は状況により変わることこそが本質なので意味を知るよりも実感するほうが早かったりします。

##大気圧の存在を確認する実験を行ってみましょう

飲み物とストローは用意しましたか？
飲み物にストローを刺し、飲み口を塞いでください。
そしてストローを持ち上げると・・・なんとストロー内の水面も持ち上がります！
ストローを持ち上げるとストロー内に負圧が発生し、大気圧がそこへ液体を押し込むからですね！

この実験において、あなたが用意した飲み物とストロー、そしてあなた自身などをひっくるめて Context です。私が冒頭にお願いした飲み物とストローは Context ではありません。強いて言うなれば想定される Context です。あくまであなたが実際に実験に使ったものが実際の Context です。

Context はラテン語で「共に織られたもの」です。何らかの手順を現実に実行する際には現実の何かが織り込まれます。現実の何物も使わずに実験することはできませんし、現実に実行せずに実験したことにするのは不正です。

Context は手順を始めるところから存在し、終了するとなくなります。飲み物とストローは実験中、 Context が持続している最中は実験機材ですが、実験が終了すればもう実験機材ではない単なる飲み物とストローです。

これは論文に対する実験ノートや実験レポートに相当すると考えるとわかりやすいかもしれません。

工学の論文では、誰が実験したのかとかいつ実験したのかは書きませんし、具体的にどこの実験設備を使ったのかは特別な施設でなければ気にすることもないでしょう。論文はモデルであり、誰にでもいつでも同じように動くどの機材を使っても再現できなければならないからです。

ですが、実験ノートには具体的に誰がいつ実験したのか、統計処理をする前の生データなどが記録されます。なぜならそれが「実際に行われたもの」であり、実行の証拠としても、再現に失敗したときなどに「実際に何が起きていたのか」を分析するための記録としても重要であるからです。No more STAP 細胞！

##Contextは必ず想定される

飲み物とストローを用意してもらいましたが、無くても実験できたでしょうか？
あるいは液体と管なら何でも良かったでしょうか？例えばおでん汁と竹輪とか？
あるいは実験っぽくビーカーとガラス管を用意してもらうべきだったでしょうか？
なんの準備もなく実行できる実験なんて都合のいいものはそうはなく、何でも用意できる都合のいい人もそうはいないでしょう。

なので、手順は必ずそれが実行できる環境を想定したものであるべきですし、 Context に言及する際には Context にそれらを含んでいるようにするべきです。

例えば実験を開始する際には機材が必要ですし、実験をする人も必ず存在します。この文章を読むような人なら飲み物とストローは簡単に用意できるでしょうが、ビーカーとガラス管は難しいでしょう。一方、もし読者に学生を想定するならば、実験室を借りることができるのでビーカーとガラス管を指定するべきでしょう。

##文章の Context

文章は必ず誰かに読まれます。よって、文章を読むときに一緒に編み込まれるものが文章の Context です。その文章の前の文章は当然読まれてるものと想定できるので Context ですが、辞書の別の項目は文章に前後してても別の話なので Context ではないでしょう。文章に背景があって読者がそれを把握していればそれも Context です。
文脈…は繰り返しになりますが私には具体的に何を指すのか分からないので Context かは分かりません。誰か知ってたら教えて下さい。

##HttpRequest Context

昔々のJavaにはServletがあって、ServletContextやHttpContextがありました。
HttpRequestを受信したところから始まる一連の手順があるならば Context に HttpRequest は必ずありますし、それが HttpResponse を返さなければならないならばそれもまた Context にあるでしょう。プログラム上に現れる他の Context も同様です。

Go の Context はあまりにも雑に扱われてますが、もし Request を受け取るコードならば Request から Response を返すまでの Context ですし、 CLI アプリなら実行して終了するまでの Context として扱うべきでしょう。Context に実際に格納されるものは、飲み物とストローを用意するように、個々のハンドラがリクエストの処理を始める前にフレームワークや単に main によって用意されるべきです。Context が格納しているオブジェクトが変化するのはまったくお勧めしませんがギリセーフですが、 Context が何を格納しているかは Context が存続している間に変化するべきではありません。

##同一の Context 

Context はアイデンティティを持ちます。例えば、あなたの実験と他の誰かの実験は同じ手順を踏んでいても別の実験だということです。あなたと友人が同じ実験室でそれぞれ課題の実験を行いレポートを書いたとします。手順は同じですがそれぞれの機材を用いてそれぞれでレポートを書くでしょう。友人のレポートがあなたのレポートの評価に影響を与えることはありません。環境は共有してますー同じ場所で実験すれば同じ環境でしょう。これは Environment です。リソースも共有してるかもしれません。共有してる設備をあなたが破壊すれば友人の実験も失敗するでしょう。ですがそれでも実験としては別々なので別 Context です。

もしあなたと友人が共同で実験を行い、一つのレポートにまとめたのならそれは同一の Context です。あなたと友人が別々の研究を同じプロジェクトの下で研究していた場合、あなたと友人は別々の研究をし別々の論文を書くでしょうが、同じプロジェクトという共通の Context も持つとは言えるでしょう。

Context switch は情報処理においてこの手のそれぞれ独立した Context である処理を切り替えて実行するものです。
Http の Contextも request ごとに独立してるでしょう。environment や resource は共有してるでしょうけどね。
Application の Context は request ごとに独立していないので request を保持することはできません。一つのアプリが複数の request を処理するため、 Application Context そのものが各 request 処理において共有されます。

##Bounded Context

さてここに戻ってきました。境界づけられた Context は単にそれぞれのケースとして想定された Context です。
例えば読者向けの飲み物とストローでの実験は、学生向けにビーカーとガラス管を用いた大気圧の実験と、想定された実行者と実行環境の違いにより境界づけられています。

ではこの「同様でない Context」はどうやって探せばいいのでしょうか？実行者と実行環境が違えばわかりやすいですね。環境が違うかわからなければー別々の人に同じ結果をもたらす手順を行わせて、同じ結果にならなければ恐らくそれは別の種類の Context です。または同じ結果になるように文章にしてもらって、突き合わせて差異があれば別の物でしょう。

繰り返しますが実験は誰にでもいつでも同様の Context ならば同様の結果になるべきもので、それはプログラムだって同じことです。大事なのはそれぞれのケースを正しく想定し、明記することです。実験手順は明記されていなければ手順とは言えません。

Context の想定が正しくなければどうなるでしょうか？
同じ手順を踏んでも Context が想定と違っていれば機材の名前がわからなかったり取り違えたり用意するのが面倒だったりして実験が失敗するようにプログラムもうまく動かない、ただそれだけの話です。

##結論

Context は「共に織られたもの」であり、実行時にユースケースやモデルに織り込まれるものです。

具体的に何が織り込まれるかは実行時に変わるし、どのようなものが織り込まれるかは何を実行しようとしているかによります。大事なのは何を実行しようとしているかを、適切な Context を想定することです。

Context の訳語や説明や理解が安定しないのは、「織り込まれるのは何なのか」という見当違いの問題に注目してるからです。それはモデルの話です。