スケジュール設定機能をつくる
機能設計の話をします。
スケジュール設定機能を作ることになりました。
これで予実管理から報告書作成までできる優れもの(予定)です。
基本的には2つのことができれば、最低限の要件になるようです。
・情報の保存
・予定の繰り返し
最初の壁
予定の繰り返し機能を考えると、「無限」という壁に直面します。
「毎週」の予定を全てレコードとして作成すると、無限にデータをインサートしなければならないという問題です。
これにはざっくりと二つの解決法があります。
- 2100年以降はレコードを作成しないなど、常識的な範囲に限る
- 設計で何とかする
前者はシンプルで、実装も容易そうです。手元のスケジュールアプリを見てみると、2120年までしかデータが登録できないようになっていました。わりと常套的な手段のように思われます。
ここでは後者の方法を考えます。気持ちの問題です。システムの寿命を自分で決めるようなことはしたくないので、1万年経っても使えるような方法を考えます。
スケジュールと実際の予定を親子関係にする案
スケジュール(例:毎月の第一日曜日に歯医者に行く)と、実際の予定(例:2024-01-07に歯医者に行く)を切り分け、前者を親・後者を子としてレコードを作成するという案です。
カレンダー上には親のスケジュールを元に表示し、各予定の詳細を保存して初めて、子レコードが作成されるようなイメージです。恐らくこういう設計だろうなというカレンダーアプリも結構見たことがあります。
子レコードは、日付をずらしたタイミングで親レコードから独立します(2024-01-14 に歯医者を一週ずらすなど)。親のスケジュールの表示ロジックから外れるためです。
基本的には問題なさそうですが、これから追加される要件を聞くと、暗雲が立ち込めてきました。
①途中でスケジュールが変わる
来年の5月からは、歯医者に行くのは3か月に1度だけで良くなるそうです。「スケジュール変更テーブル」を作れば対応できそうですが、既に独立した子レコードたちはどうすべきでしょうか。また、過去のデータにスケジュールの変更は反映すべきでしょうか。
②独立した子レコードに変更が反映されるのか分からない
次月から、別の歯医者に行くことになりました。この変更を未来の予定すべてに反映させたいのですが、せっかく独立させた子レコードに反映してよいものでしょうか。また、ユーザーは反映される方とされない方、どちらを期待するでしょうか。
これらの問題は、親子関係の複雑さに起因します。つまり、今後の予定が
- 親のスケジュールのみに存在している
- 親のスケジュールに紐づく子レコードとして存在している
- 親のスケジュールから独立した子レコードとして存在している
の3つの形態をとり、それらが同様にカレンダー上に存在していることが、問題の原因になっています。
子レコード(実際の予定)を複製する案
こういった手もあります。
前段での子レコードに、スケジュール情報も保持しているようなイメージです(2024-01-07に歯医者に行く + これは毎月第一日曜日の予定である)。
予定の繰り返し登録は、該当の子レコードを複製する形で行います。未来に予定がある場合は、再作成します。
メリットは、未来のスケジュール変更が容易で直感的な点です。未来の予定のみを変更する形で繰り返しの登録を行うため、変更の影響の及ぶ範囲が直感的になります。特にこのメリットは、過去の履歴をかえてはならない予実管理において有効です。
一方で、デメリットも大きいです。
無期限で複製することは結局できないため、スケジュールが登録された子レコードを定時で自動複製することで、疑似的に無期限の予定を表示しています。過去に及ぶような変更も、実現できないわけではないですが直感的ではありません。
考えをまとめ直して気づいたこと
スケジュール機能というものを考えたとき、設計上難しいというよりも、直感的に操作させるのが難しいというところにネックがありそうです。
実際に開発したときは、子レコードを複製する案で作りました。予実管理がそちらの方が分かりやすくなるというのが決め手でした。
それに加えて、個人的に後者の手法を気に入っている点が一つあります。尺取虫が進むように、自己複製しながら無期限のスケジュールを表現しているところです。気持ちの問題ですが、気持ちも大事です。