概念モデルで実装方針の認識合わせ

経緯

すでに実装済みのスケジュール適用機能を改修し、分割適用を行うという案件があったのですが、レビューを行っているとスケジュール適用のための予定と実際のスケジュールの同期がよく取れていないと言うことがありました。
なれた製品での開発だったので設計レビューせず実装してもらったのをレビューしたのですが、そもそもの方針の時点で共有してもらってから出ないと手戻りが発生する可能性があるので、修正の認識合わせとして概念モデルレベルでのオブジェクトの責務割り当てが使えそうなので振り返ってみたいと思います。

改修内容(簡略) 詳しくは書けないので、大分簡略化した既存仕様と修正後の仕様は以下のようになっています。

  • 既存仕様(簡略)

    • 予定には日時指定曜日と時間指定での繰り返しがある
    • 日時指定予定は適用後に削除される
    • 曜日と時間指定での繰り返しは指定した曜日、日時で毎週実行されるので適用後に削除される
    • 予定には適用設定値があり適用時に対象の設定値適用設定値にする
      • 例えば適用設定値が6であれば予定の時間になれば設定値を6にする
  • 修正後仕様(簡略)

    • 予定には日時指定曜日と時間指定での繰り返しがある
    • 日時指定予定は適用後に削除される
    • 曜日と時間指定での繰り返しは指定した曜日、日時で毎週実行されるので適用後に削除される
    • 予定には適用設定値適用分割数がある
      • 例えば適用分割数が3で適用設定値が6、適用開始時の設定値が10秒間隔で4->5->6と分割して適用される
    • 予定分割適用中は対象の設定分割適用中フラグをONにしておく
    • 予定分割適用中に対象の予定分割適用中フラグをOFFにする

このように改修後は予定に適用分割数が増えています。
上の仕様の一覧には上がってきませんが、予定を適用するには予定から作られたスケジュールが実際の適用タイミングの制御を行なっています。例えば月曜21時の予定であればスケジュールとしては7/11 21:00といった具体的なものになります。そのため、予定が消されたらスケジュールでの実行もやめるし分割適用中であれば分割適用中フラグをOFFにするといった制御が必要になります。こちらの仕様一覧からエンティティおよび属性、エンティティ間の関係を概念モデルとして表すと以下のようになります。

概念モデル1
このように要件から単語を抽出してモデリングを行うと言うのはユースケース駆動開発実践ガイドに詳しく載っています。

ユースケース駆動開発実践ガイド

ユースケース駆動開発実践ガイド最初のモデルが作られたら、そこから深掘りを何度かして行って概念レベルから実装レベルのモデルを作り上げていきます。ユースケース駆動開発実践ガイドではモデリングを行う際に以下を注視して行います。

10.現実世界(問題領域)のオブジェクトに焦点を合わせなさい。
9.オブジェクト同士の関係を表現するため、汎化(isa)関係および集約(hasa)関係を利用しなさい。
8.最初のドメインモデリングにかける時間は2時間に限定しなさい。
7.問題領域中の主要な概念を中心にクラスを構成しなさい。
6.ドメインモデルをデータモデルと勘違いしてはいけません。
5.オブジェクト(単一のインスタンスを表現する存在)とデータベースのテーブル(モノの集合を含む存在)とを混同してはいけません。
4.ドメインモデルをプロジェクトの用語集として使いなさい。
3.名前が曖昧になることを避けるため、ユースケースを書く前にドメインモデルを書きなさい。
2.最終的なクラス図が、ドメインモデルと正確に合致することを期待してはいけません。しかしこの2つは、何らかの形で相似の関係にあるはずです。
1.ドメインモデルには、画面やその他のGUI固有の部品クラスを配置してはいけません。

今回は概念レベルでのオブジェクト間の関係として、以下のように進められていました。(実際には各オブジェクト間の関係について共有されたのではなくレビュー時に実装内容から割り出した)

概念モデル2

また、こちらの操作を行うのには3種類のスレッドが存在している。

  • 5秒間隔での予定同期用のスケジューリング(1段階目のみ)スレッドおよび予定削除時のスケジュールキャンセルスレッド
  • スケジュール実行用スレッドとスケジューリング(2段階目以降)

一見すると問題なさそうですが、以下の操作時に正しく動作しないであろうことが把握できます。

  • 分割適用中に対象の予定を削除し、すぐに適用される予定を新規で作成すると、新規予定のスケジュールが動いた後に削除済み予定のスケジュールが動作し分割的用中フラグがoffになることで、新しく作った予定のスケジュールも停止になる

↑の動作に対応するのであれば各スレッドで予定毎でのロックを取るようにし、予定削除があればそのスレッド内でスケジュールをキャンセルし、設定値の分割的用中フラグをoffにするなどで対応はできると思います。

それよりも問題なのは設計せずに実装を進めることで、作ってから問題に気づくことだと思うので改修時の注意としてすぐに実装するのではなく設計をちゃんとする(実装の方針として適切なレベルのモデルを描いて欲しい)。詳細レベルのモデルであれば実装時レビューの修正で良いと思いますが概念レベルのモデルでづれていると手戻り発生の可能性が出てくるので注意説明のためブログに書いていみました。逆に言えば概念モデルレベルで抽象化したオブジェクトでの責務や関係について認識合わせすることは設計時のレビューで有用そうです。

また、一般的にモデリングと言ったらビジネスロジックなどを指すことが多いですが、今回のスケジュールなど実装のために必要なオブジェクトについても責務や関係があるのでモデリングは行なっておいて良さそうです。