はじめまして、介護事業者向け経営支援サービス「カイポケ」 のエンジニアの大縄です。
本記事では、カイポケの障害児支援領域のリプレースで実施したドメインモデリングについて、実際のドメインを題材にどのように実施したかを紹介させていただきます。
ドメイン駆動設計を参考に実施しているところもありますので、ご興味のある方の参考になれば幸いです。
リプレースの背景
障害福祉の制度は概ね 3 年に 1 度改定されます。プロダクトも新制度に追従していく必要があるのですが、制度が複雑であり開発日程もタイトであることから、プロダクトの仕様やコードベースを最適化することを犠牲にした結果、仕様が複雑化し、それに引きづられてコードベースも複雑度が高く肥大化した状態となっていました。
リファクタリングなどの改善は行なってきたものの、「複雑化した仕様」「肥大化したコードベース」に対して変更を入れることは容易ではなく、ユーザーへの価値提供を増やしたくても増やせない状況が続きました。
このままではまずいと感じつつもなかなか根本解決に踏み切ることができなかったのですが、次回の制度改定まで期間があり、ドメインやプロダクトに関する知識も蓄積できてきた、というタイミングが巡ってきたことから、根本的な解決としてリプレースを行うことになりました。
リプレースでは大きく以下の 3 つを行いました。
- 既存の仕様を参考にしつつも、複雑さを排除した新たなドメインモデルを設計・構築する
- 言語の表現力も借りて、基本に沿って秩序あるコードベースを再構築する
- ドメインモデルとコードベースに対し、変更容易性を維持する仕組み作りや取り組みをする
本記事では、「1. 既存の仕様を参考にしつつも、複雑さを排除した新たなドメインモデルを設計・構築する」に対する取り組みの一例を紹介させていただきます。
より詳細なリプレースの背景については「ユーザーへの価値提供機会を増やすためにリプレースを決意した話」で説明されていますので、是非ご覧いただければと思います。
題材とするドメインは「学校休業日」
リプレース対象であるいくつかのドメインのうち、「学校休業日」というドメインを題材に説明していきたいと思いますが、まずは題材の前提知識として「学校休業日」をモデリングした背景について説明します。
障害児支援領域には、学校に就学している児童に対して授業終了後または学校が休みの日に生活能力の向上のために必要な訓練や社会との交流促進などの支援を行う「放課後等デイサービス」というサービスがあります。
このサービスの利用料金の一部は自治体に請求するのですが、「授業終了後にサービスを提供した場合」と「学校が休みの日にサービスを提供した場合」で料金設定が異なり、また、サービス内容によっても料金が細かく分かれています。
カイポケには、日々のサービス提供の内容から利用料金を算出できるよう、あらかじめ学校の休業日を設定するための機能があり、この機能もリプレース対象の一つとしていたため、「学校休業日」をモデリングすることになりました。
2 つのステップで実施するドメインモデリング
ドメインモデリングの定義は様々あると思いますが、以下 2 つのステップをドメインモデリングと捉えて実施しました。
【ステップ1】ドメインの理解
- 対象のドメインについて調べ、関係性や決まり事を整理する
【ステップ2】ドメインのアプリケーション設計
- 対象のドメインをアプリケーションで実現するための設計を行う
以降にそれぞれの詳細を説明します。
【ステップ1】ドメインの理解
このステップでは、対象のドメインについて調べ、関係性や決まり事を整理します。
まずは、放課後等デイサービスにおける休業日がどのように定義されているのかを調べました。
厚生労働省の資料(平成27年度障害福祉サービス等制度改正に関するQ&A(平成27年3月31日))によると、以下のように定義されています。
・学校教育法施行規則第 61 条及び第 62 条の規定に基づく休業日(公立学校においては、国民の祝日、日曜日及び土曜日、教育委員会が定める日、私立学校においては、当該学校の学則で定める日)
・学校教育法施行規則第 63 条等の規定に基づく授業が行われない日(例えば、台風等により臨時休校となる日)又は臨時休校の日(例えば、インフルエンザ等により臨時休校の日)
なお、学校が休業日ではない日に、放課後等デイサービスを午前から利用した場合であっても、休業日の取扱いとはしない。
上記を入り口に、学校教育法施行規則 を調べて「教育委員会が定める日」とはどんな日があるのかを把握したり、国民の祝日はどのように定められるのかを調べたりすることでさらなる理解を深めていきました。
また、今回の対象機能が「あらかじめ学校の休業日を設定するための機能」なので、事業所がいつどのように休業日を知るのかを実際の事業所にヒアリングさせていただいたりもしました。
そして、これらの内容を調査しながら整理し、以下のように図示していきました。
クラス図に近い図ではありますが、ステップ1では実装を意識せずにまとめていきました。(ドメインを理解できる形であればどのような形式でも良いと思っています。)
【ステップ2】ドメインのアプリケーション設計
このステップでは、ドメイン理解の図をもとにドメインをアプリケーションで実現するための設計を行います。
設計する際には『エリック・エヴァンスのドメイン駆動設計』で紹介されている "集約(Aggregates)" というパターンを参考にしました。
集約とは、関連するオブジェクトの集まりであり、以下のように実現されると理解しています。
集約の中からルートとなるオブジェクトを決め、変更は必ず集約ルートを経由する
- 集約ルートが集約内の不変条件(データが変更されるときに維持されなければならない一貫性のルール)をチェックする最終的な責務を負う
集約単位でデータの取得・永続化を行う
- 永続化の入り口には集約ルートしか渡せないし、集約ルートしか返せない
集約を利用した処理の流れを簡単に図示すると以下のようになると考えています。
カイポケ障害児支援領域のリプレース前のコードは、同一テーブルに対する処理が色々な場所で実装され、不変条件のチェックもそれぞれ実装されているケースが多々ありました。よって、集約の概念を取り入れ、関連する情報に対する不変条件のチェックや永続化処理を一箇所に集めることで重複を排除し、秩序あるコードベースを構築しようと考えました。
「学校休業日」の集約を定義する
ここから実際に「学校休業日」をアプリケーションで実現するための設計をしていくのですが、まずは以下のように、アプリケーションとしてどのように学校休業日が設定できれば良いかを考えました。
公立の学校は市町村・または都道府県の教育委員会によって休業日が決まるが、私立の学校は学校ごとに校則で定められることから、学校ごとに休業日が設定できればどちらもカバーできると考える
学年ごとに休業日が異なるケースや臨時休業日があることから、利用者個別に休業日を設定できるようにもする
土日、国民の祝日はユーザーが設定できるものではないため、学校休業日を設定する際のデフォルト値として利用する(国民の祝日はシステムのマスタデータとして管理されているものを使う)
上記をもとに集約を定義し図示していきました。
集約を定義する際に考慮しなければならないこととして、「集約は小さくする」ということが挙げられます。なぜなら、データの取得・永続化やロック(楽観的排他など)が集約単位で行われるためです。集約が大きすぎると、パフォーマンスの悪化や複数ユーザーで作業ができないといった問題が発生してしまいます。そのため、「不変条件は何か」だけでなく「どのようなユースケースがあるか」ということも考えながら大きくなりすぎないように定義していきました。
「学校休業日」の場合、ドメイン理解の図に記載されているように、基本的には年度単位で休業日が決まるが月初や当日に初めて休業日を知るケースもある、ということから、何度も更新が発生することが予想され、また、利用者に対するサービス提供の業務が月単位のサイクルである、などの理由から月単位の集約としました。
また、名前付けについてもチームで合意をとりながら進めていきました。ここで定義した集約はそのまま実装に反映されるため、和名だけでなく英名も決め、アプリケーションで一貫して同じ名前を使えるようにしました。
ここでひとまず「学校休業日」の集約が定義できたわけですが、定義した集約をを使用して実際に利用者に対するサービス提供を登録することを考えると、現状のままでは利用者と学校が関連づいていないため月間学校休業日を特定できないという問題があります。
よって、ステップ1のドメイン理解に戻り利用者と学校の関連付けについて理解を深め、ドメイン理解の図を更新していきました。(利用者と学校の関連付けを「所属学校」として追記)
そして、ドメイン理解の図をもとに同じように集約を定義していきました。加えて、利用者に対するサービス提供を登録するときに集約がどのように使われるかについても記載し、最終的には以下の集約定義となりました。
このように、必要に応じてステップ1とステップ2を繰り返しブラッシュアップしていきました。
ドメインモデリングは今後も続く
今回の成果物である「ドメイン理解の図」と「集約設計の図」は一度限りの図ではなく、メンテナンスし続けていくドキュメントの 1 つとしており、実際の改修の際にもまずはドメインモデリングをしてからバックエンド、フロントエンドの開発を行っています。
おわりに
カイポケの障害児支援領域のリプレースで実施したドメインモデリングについて、実際のドメインを題材にどのように実施したかを紹介させていただきました。
モデリングの対象となったドメインは他にもいくつかあるのですが、振り返ってみると、チームで議論しながら進めていくことの難しさを感じることもあったように思います。しかし、ドメインに対する理解が深められ、また、チームでの意思決定が形として残ることが後の開発の助けにもなりましたので、やって良かったなぁ、と改めて思いました。
今回紹介させていただいた活動が少しでも参考になれば幸いです。