本記事は、 DDD-Community-Jp Advent Calendar 2020の14日目です。
はじめに
@t2-kob さんがこの記事で言っていた、モデルの不吉なにおいって表現が面白いなって思いました。
リファクタリング第2版にて、リファクタリングの必要性を感じさせる、コードによく見られる問題のことを、「コードの不吉な臭い」と表現されています。
上で取り上げた記事では、それになぞらえて「モデルに対する皆の理解がずれてしまう」「モデルに対しての違和感が発生する」の状態をモデルの不吉なにおいと表現しています。
自分も似た感覚を持ったことがある1ので、何かしらこれを書いておくと今後のモデリングで役立ちそうな気がしているので、書いてみたいと思いました。
ここでは「モデルの不吉なにおい」というのを、「モデリングか実装の手を止め、モデル自体に立ち返って見直す必要性を感じさせる場面」としておきます。
モデルの不吉さを感じる瞬間
モデルに出てくる言葉と実装されているコードの言葉が違う
せっかくモデルで表現した内容をそのままコードに落とさずに、モデルに無い名前を使ってしまうことがあります。
こうなってしまう原因はいくつかパターンがあると思い、
- 単純に名前を間違えてしまう
- 英名に変更する時に、実装する人がそれぞれ別の英名を使ってしまう
- 実装をしていくうちに「こんな概念もありそうだよね」とコードに追加したけど、モデルにフィードバックをしない
- 後述の「どこから来たかわからない概念」でも取り上げます
これの対応策としてはレビュー時にモデルと実装を確認する。必ず実装後にモデルへフィードバックするなどプロセスで決めてしまうやり方もあれば、コードからモデルを生成するようにして乖離を防ぐやり方もあります。
名前に対する違和感
これもよくあると思います。
何かしらの概念に苦し紛れで名前を付けたのもあれば、最初は良いと思っていた名前が後々見直してみると違和感が浮き彫りになってしまったりするパターンです。
リファクタリングの「不可思議な名前」2の中では、「良い名前が思いつかないことは設計が固まっていない兆候」と書かれています。実装レベルの話ではありますが、モデルに関しても例外では無いと思われます。名前があやふや、お互い言っていることが変わってくる場所については、見直す価値があります
この違和感のセンサーを高めるには、声に出してモデリングしたり、実際にコードに落とし込むことが有効打の一つです。 (なので、前節のモデルとコードの乖離があるのはとても困ってしまいます)
つながりを見出すことができない
EventStormingやユーザーストーリーマッピング、業務フロー図などの時系列で表現するモデルでよく見かけるのですが、
イベントとイベントのつながりや、ユーザーの前後の行動につながりを感じ取れないのも一旦立ち止まる価値があります。
これは何かしら重要なモノを見失っていたり、まだ明示的になっていない概念が存在している可能性があります。
この不整合を見つけるには、声に出してシナリオをウォークスルーしてみるのも一つの手段です。
何かしら不整合があった時には、間に空のイベントを置いてみたり、そもそも時系列がおかしいのかもしれない、と疑ってみます。
ふきだしの多さ
概念モデル図みたいなものを書く時に、「◯◯というルールがある」など、そのモデルが持つルールをふきだしで書くことがあります。3
そこである一箇所にふきだしが集中するようだと、それはルールが集中している → 1つのモデルが持つ役割が多すぎるサインかもしれません。
必ずしもそうとは限らないですが、もしかしたら概念が絡み合っている可能性があるかもしれないので、一度立ち止まって考えてみる余地はあると思います。
ふきだしが集中している例
開始時間、予約時間、日時とモデルは分かれていますが、それを一括にした概念にルールが集中しています。
時間に対するルールと、日にちに対するルールが混在しているので、最終的には予約の時間を表現するものにはなりますが、
その内部のモデルそれぞれに対してルールが紐づくようにした方が良さそうだと、後々判断しました。
ほぼ一緒の関連を持つ別の概念
同じ属性を持つ別の概念に対しては注意をしたほうが良いかもしれません。
同じ属性を持っている別々の概念が違う振る舞いを持つのであれば問題ありませんが、
まったく同じ振る舞いを持つのであれば、別の概念に区別する理由を再考します。
区別する理由が無いのであれば、それはどちらかに寄せてしまっても良いかもしれません。
関連が一緒の別の概念の例
予約希望と予約済み。
これらは予約が成立する前と予約が完了したものとして概念を分けたかったが、持っている属性としては同じ。
そして私達がモデリングしている状況では、これらの振る舞いが特に変わることは無かったです。
予約が成立する前、予約が完了したものを表現するなら、内部でステータスを持つことになるのが一般的かもしれません。
どこから来たかわからない概念
モデリングをしていると、ついつい楽しくなっていろんな広がりを見せます。
その中では、当初無かった概念もチラホラと顔を見せてきます。
それが知識の噛み砕きを行った結果出てきた概念なのか、それとも電波を受信して知らない世界から輸入してきた概念なのかは、一度立ち止まって考える必要はあると思います。
謎の概念を真面目に取り扱った例
たとえば時間を15分単位としたい。これは組み込み型のDateTime型では表現出来ないから、何か良い名前は無いかと考えたときに、「コマ数」としました。
でも実際にユースケースの中ではコマという概念は出てこない。
10:00から4コマで、というインターフェースで作ってみても、内部的には通常のDateTime型に変換しています。
結局コマという概念は要らないという判断になりました。
実装を始めたときのぎこちなさ
モデルを実装したときに感じる特有の違和感もあります。
- 予約自身が自分自身をキャンセルするのおかしくないか?
- 予約自身が自分自身を生成するのおかしくないか?
- そもそも予約の中で予約済み、キャンセル済み、といったステータスを持たせるのは変ではないか?
実装に落とし込むときにぎこちなさを感じることもあれば、実装していく過程で、チームメンバーそれぞれが認識しているズレによるぎこちなさもあります。
これは、はじめにで取り上げた記事で言っていた「モデルの不吉なにおい」だと思われます。
エリック・エヴァンスのドメイン駆動設計の第8章ブレイクスルーでも、予想外の要求につまづき、設計やコードが複雑さを増していく話があります。4
モデルとコードは互いにフィードバックしあって洗練させていくので、それが複雑さを増していっているのは、おそらくモデルに立ち返って考え直すときのタイミングかもしれません。
ずっとモデリングをしている
違和感というわけではないですが、これはひとつの不吉なにおいだと感じます。5
時間を区切らずに、ずっと分析してモデリングをしているのは、あまり良い傾向ではありません。
モデルと実装は相互にフィードバックをし合うことで、お互いを洗練させることができます。
片方にだけ時間を費やすのは良くないので、ちゃんと時間を区切って交互に行き来することを心がける必要があると思います。
おわりに
いくつか自分がモデリングをしていて感じていた不吉なにおいを書いてみました。
もちろん上記で書いたようなことが起きたからと言って、必ずしもモデルを見直すことは無いと思います。
あくまで立ち止まって考え直すヒントとして、活用してもらえたら嬉しいです。
参考文献
-
自分の場合は、このモデル嘘くさいとか、生煮えとかって言うことが多い気がしています。↩
-
出典:リファクタリング第2版p.74 「不可思議な名前」↩
-
これはUML的なルールではないので、書かない人もいると思います。もしくはモデル図に付箋を書いている人もいるかもしれません。↩
-
エリック・エヴァンスのドメイン駆動設計 p.197 「悪くないモデルなのだが…」↩
-
モデルじゃなくて、プロジェクトの不吉なにおいかもしれません↩