FEHで学ぶDDD　前編　-エンティティとコンテキスト-

#エンティティとはなんであるか？
というかエンティティはなぜエンティティであるか？をゲームを用いて説明してみます。
題材はファイアーエムブレムヒーローズ（FEH）ですが、ガチャとかランダムでユニットが手に入るゲームならばみんな同じようなもんかと思います。艦これとかポケモンの愛着のあるキャラに置き換えて読んでみてください。

##まずガチャを回します！

![FEHの主人公とすら言われる男ラインハルト](https://qiita-image-store.s3.amazonaws.com/0/151783/414ce9d7-2b05-5a22-92ed-8e7356024958.png "FEHの主人公とすら言われる男ラインハルト")


出たのはラインハルト、通称ヤクザ。戦力のインフレ著しいゲームにも関わらず２年近くも最強格の座を保っているうえにレア度が低くて無課金でも普通に来てくれる凄い奴です。
さて、ゲームというかアプリでは終了時にデータは保存しないと基本的に消えてしまいます。このガチャから出てきたラインハルトもアプリを終了したら消えてしまってもいいものでしょうか？

そんなわけないですよね。せっかく出たんですから次に遊ぶ時にも存在してくれないと困ります。アプリをアンインストールしたりスマホを交換してもインストールしなおしたら戻ってきてくれたらなおいい。将来的にはサービスが終了してもスタンドアロンのゲーム＆データとして残っていてほしい。

##エンティティ
###再構築したデータを同じものとして扱いたい

アプリを終了するとメモリに展開されていたデータは破棄され、次にアプリを起動したときに再度作成されます。この二つのデータは「物理的にという意味も含めあらゆる意味で同じもの」でしょうか？もちろん違います。値としては同じですが物理的に違いますし、equals()でアドレスのハッシュ値を比較する場合は以前のデータと再現したデータは別ハッシュ値になるでしょう。
でも、「こないだのガチャで来てくれたラインハルト」という言い方はしても「こないだのガチャで来てくれたラインハルトと同じ値を再現した別のラインハルト」という言い方はしません。後者のいい方は単に長いというのもありますが、愛着があってわざわざ別のものだといいたくないというのもあります。

この、アプリやサービスよりも長く残っていてほしい存在、一度データが破棄されある意味では連続性を失っているにもかかわらず同じもの・以前のものと連続しているとして扱いたいもの、「連続しているとしてユーザとシステムが合意したもの」がエンティティです。（[こんな記事を書きました。](https://qiita.com/turanukimaru/items/68bd00f583d117b1edcf)）
エンティティの説明として一般的には人とかの物理的な存在を例にすることが多いですが、それは物理的に存在しているものは自然とアプリやトランザクションより長く存在することに合意できるからです。このラインハルトはユーザとapplicationでの「同一性を持って存在し続ける」という合意によりエンティティとなるわけです。（なおガチャの場合はラインハルトが出たという「運営との合意」が成立するので存在は一層強固になります。）

##同一性
###レベルアップしても同じものとして扱いたいという話

アプリを再起動して同じデータを再構築したらそれは同じキャラである、とします。
では、レベルが上がって違うデータになったらそれは別のキャラでしょうか？レア度を上げて真の性能を引き出したら別のキャラでしょうか？
そんなわけはないですよね。多くのプレイヤーは同じキャラが成長して強くなったと思うはずです。このように状態（属性・関連するオブジェクト）が変化したとしても同じものとして扱いたい、これが同一性（のうちの半分）です。連続した同一性とでも言うべきでしょうか。
![レアリティが上がりレベルも上がりましたが同じユニットです](https://qiita-image-store.s3.amazonaws.com/0/151783/000135d7-fa77-c392-b5f0-25c1af1e3203.png "レアリティが上がりレベルも上がりましたが同じユニットです")


##同一性
###同じ名前同じ性能のユニットを区別できないと大変困るという話
さらにガチャを回してもう一人同じ性能のラインハルトが出たとします。（レア度が低いと普通によくある光景です。）

![二人と言わずいくらでも出てきます](https://qiita-image-store.s3.amazonaws.com/0/151783/a06496ce-56a4-7454-441a-2b9764253fbb.png "二人と言わずいくらでも出てきます")

さて、FEHではユニットがスキルを覚えたり他のユニットから継承したり複数持っている中で装備するものを選んだりします。
LV1では新しいスキルを覚えられないので代わりに武器を外してみます。
では、私が「ラインハルトの武器を外した」場合、想定する結果は次のうちどちらでしょうか？

-一人の武器が外れる
-ラインハルト全員の武器が外れる

論理的に考えれば全員ラインハルトなので全員の武器が外れるはずですが、プレイヤーとしてはせっかく沢山いるんだから別々の武器やスキル構成にしたいと思うことも多いでしょう。
そこで、「ラインハルトのうち一人の武器を外す」こととします。仮に操作して一番左側の武器を外した場合、想定する結果は次のうちどちらでしょうか？

-一番左の武器が外れる
-真ん中の武器が外れる
-一番右の武器が外れる

![image.png](https://qiita-image-store.s3.amazonaws.com/0/151783/a29d7528-81cc-9ca5-7423-e5543713f69f.png)


論理的には「ラインハルトのうち一人のスキルを変更」した結果として実際に一人だけ変わっているのでどれも正しいはずです。実際に戦闘に参加させるときに武器の外れてるユニットを選べばいいだけなので何の違いもありません。
この「全く同じオブジェクトが複数あったとして、そのうちの特定の一つを明確に区別することができない」というのが「同一性がない」ということです。

でも、どれが変わっていても同じはずなのですが、実際には一番左のスキルを変えたので一番左が変わっていて欲しいですよね？そうでないと変更したラインハルトを使おうと思ってうっかり変更してないほうのラインハルトを使ってしまうかもしれません。
左側のラインハルトを変更したら左側のラインハルトが変更される、「全く同じオブジェクトが複数あったとして、そのうちの特定の一つを明確に区別することができるし、変更されたオブジェクトは変更する前のオブジェクトと同一である」というのが同一性があるということです。

たいていのエンティティは同一性を必要とします。せっかくガチャを回して出たユニットを区別できなくてはガチャを回した甲斐がありません。また、一見同じように見えるデータでも実は意図があって（もしくは違いをデータとして表現しきれなくて）区別したい場合も珍しくありません。例えば物理的な存在は同一性を持ちますので、物理的存在を代表させたエンティティは同様に同一性が無いと困ります。
なお全てのオブジェクトが同一性があるわけでもエンティティであるわけでもありません。FEHでは最近クイズマップが追加され、用意されたキャラとマップで戦います。戦闘に参加するユニットは用意された能力であればいいのでその同一性はマップをクリアするまでで十分ですし、装備を変えられるわけでもありません。だからエンティティではなく普通のオブジェクト、という事ですね。
![この戦場で出てくるだけの借り物のユニットと敵たち](https://qiita-image-store.s3.amazonaws.com/0/151783/df90dd46-2dbb-2fcf-dba2-a8d8ee492494.png "この戦場で出てくるだけの借り物のユニットと敵たち")

##識別子
###同一性を十分に与えるという話

アップデートで、色の付いたお気に入りマークを付けられるようになりました。

![ハートの色が違いますね](https://qiita-image-store.s3.amazonaws.com/0/151783/75e02155-4004-99d3-52a6-d06485442541.png "ハートの色が違いますね")

同じ絵同じ名前であってもこの色を被らないように割り振っていけば、明確に区別できますね（どんな能力のユニットにどの色を割り振ったか覚える必要はありますが）。
これ以前は一見して区別がつかないため装備の違うユニットと取り違えて戦闘に参加させたりする事故が多発しました。
このように特定のオブジェクトを明確に区別することのできる何か、アイデンティティを十分に与える何かをアイデンティファイア（＝ID、識別子)と呼びます。
FEHでは同じ名前のユニットが複数存在するので名前は識別子になりませんが、逆に被らないならば名前を識別子にすることもできます。
なお一見わかりませんが内部的には「入手順」を持っており、ガチャは連続で回すことはできますが同時に複数回すことはできないため入手順は被ることはなく、これは識別子として機能します。エンティティの整合性を保つにはIDはできる限りあったほうが良いのできっと何かしら使っているのでしょう。

##境界付けられたコンテキスト
###ミニゲームはゲームの一部だけど明確に別のルール

FEHは本編はSLGですがリズムゲームが追加されました。

![装備してる武器がそのまま違いになってるのわかりますか？](https://qiita-image-store.s3.amazonaws.com/0/151783/36c7ae10-f846-2a0d-410b-4aa52c13c06e.png "装備してる武器がそのまま違いになってるのわかりますか？")


さて、リズムゲームはSLGと同じように操作できる同じようなルールのゲームでしょうか？
そんなわけないですよね。SLGとリズムゲームは操作方法も楽しみ方も違う全く別のゲームです。
では、FEH本編と関係のない全く別のゲームでしょうか？これもそんなわけはなくリズムゲームも立派なFEHの一部です。
このように一つのシステムの中で別のルールや前提が適用される場面というものが存在し、「同一のルールや前提が適用される場面」を「コンテキスト」と言います。SLGとリズムゲームではルールが違うので別コンテキストである、ということですね。
そしてややこしいことにこのコンテキストというのは「存在し、場面が同じなら同じなのだが具体的に何であるかは誰も知らない」というものです。
なので場面を明確に区切ったもの、例えばSLGやリズムゲームのそれぞれのパートを「境界付けられたコンテキスト」と呼びます。重要なのはコンテキストそのものではなく、何かを境界にコンテキストが別のものであること、コンテキストに結びついたルールが変わること、というわけですね。

##同一エンティティの別コンテキストでの別オブジェクト
###ミニゲームでも同じユニットを使いたい

SLGとリズムゲームとではルールが違うわけですが、登場するオブジェクトは同じでしょうか？
もちろん同じでもいいのですが、同じオブジェクトに別のゲーム用の機能を追加していくとクラスが肥大化してしまいますし、必要のないルールが混ざれば取り違えが起こることもあるでしょう。
リズムゲームではタイミングよくタップするだけであるため盤面上を移動する機能や戦闘能力は必要ありません。よって、ゲーム画面に表示されているキャラクターはSLGのユニットとしてのオブジェクトである必要はないでしょう。私ならタップすると武器を振るというだけのオブジェクトとして扱います。
一方で外見や声は同じユニットとして扱いたいですし、ユニットは一人ひとり装備によって外見が変わるのでそれぞれのユニットと同一として扱いたいです。戦場で戦うお気に入りの姿のラインハルトをそのままリズムゲームで使いたい、ということです。画像のラインハルトがそれぞれ武器が違うのわかります？
このようにエンティティは他の場面で別のオブジェクトとして登場することがあります。
エンティティは連続した同一性を持つという合意から存在しているため、別オブジェクトであっても同じものとして扱えるということですね。

##エンティティは物理的に存在するなにかを代表することもできる

ところでラインハルトはアクリルフィギュアにもなっています。
例えば私が盤面を模してフィギュアを並べたり、リアルで駒を動かしたらゲームの駒も動くようなUIを作ったりしたらゲームのキャラと物理的に存在する駒が同一視できるという事になります。
つまり、ゲーム的存在と物理的存在が同一エンティティの部分であるといえる、ということですね。
DDD本とかでよく出てくる物理的存在をエンティティにして云々というのはこういう話です。

![シークレットがラインハルトです](https://qiita-image-store.s3.amazonaws.com/0/151783/4a3eae17-f112-d363-34fc-2aacdb6bbe9b.png "シークレットがラインハルトです")


##書き溜めなくなったから終わらなかった！
###次回、FEHで学ぶDDD　後編　-ルートエンティティとトランザクション-