[続開発プロセス#9] データベースの設計から入る

前回までに、サンプルとして作るメモアプリケーションと、その要求項目をまとめました。本来は、そこから「要件定義」をするところかもしれませんが、要求+UIデザインがあれば、基本的には要件と呼ばれる項目もピックアップされていると考えて、今回はシンプルなアプリケーションでもあるので、割愛します。ここから分担して作業するような場合には確かに要件定義も必要かもしれませんが、ここで紹介しているアプリケーションだと表現の違い程度のものしかありませんので、文書化する手間を省きます。

実際に作成するものが決まって来れば、全体の機能からだんだんと詳細化する様な方法がまず1つあります。これに対して、まずはデータベースのスキーマを確定させ、ドメインをデータベースの中に実現することを優先する方法もあります。複雑なアプリケーションの場合は前者のように、機能を分析して、どういう構成をするのかということを先に考え、並行してデータベースの設計をするのが良いと思われます。一方、シンプルなものは、データベースをまずは設計して、UIとDBの間をどのように埋めるのかということを考える方が効率が良いと思われます。ということで、今回は、まずはER図レベルのものを作ることにします。要求項目等から、以下のようなER図あるいはクラス図を作成しました。

前者はER図、後者クラス図です。ここでは、どんなテーブルがあって、どんなフィールドがあって、関連付けをどう行うかということが記載されていればいいので、どちらの図でも大きな違いはないと思います。見ての通りAstah*を使っているので、どちらかと言えば、クラス図の方が自由度が高いこともあって、私は通常はクラス図で記述します。クラス図では付加的な情報はステレオタイプを活用することで、ちょっと見慣れるのに時間がかかるかもしれませんが、記述は可能なので、そうした仕組みを用意しています。

要するに、メモとカテゴリの2つのテーブルがあるということです。メモに日付時刻のdtフィールド、メモのmemoフィールドがあるのはいいとして、2レベルのカテゴリ設定のために、2つの外部キーフィールドtop_category_id、sub_category_idを用意して、カテゴリつまりcategoryテーブルのcategory_idフィールドに関連づけています。カテゴリは、目に見えるデータはcategory_nameだけですが、階層化の管理をここではテーブル内に持たせることにします。本来は、カテゴリとカテゴリ間の関連を別々のテーブルで表現するのが役割を分離した設計になるかもしれません。ですが、2レベルということで、主キーとなるcategory_idと、自分の上位のカテゴリを示すparent_category_idのフィールドを用いるだけで概ね問題ないと判断して、このようにしました。parent_category_idがNULLであれば大分類、category_idに存在する値があれば小分類とすることができ簡便です。もちろん、1つの小分類項目は、1つの大分類項目にだけ所属できるので、完全にツリー状の構造になるでしょう。前回のUIサンプルのカテゴリ一覧(ページ左側)にあるような大分類、小分類の構成にするには、例えばテーブルのデータは次のようになります。

category_idparent_category_idcategory_name
1仕事
2ホーム
3趣味
41毎日
51レポート
61進行中
71気付き
82レジャー
92学校行事

本来、こうした状態をキープするためには、カテゴリの修正ページはそこそこ複雑になります。もちろん、名前を書き直すのは容易ではありますが、大分類を消した時、小分類も一緒に消すのかどうか、あるいは残すのか。また、それぞれの分類を消した場合、その分離を設定しているメモの方はどのような扱いにするかなど、検討事項はいろいろありますが、今回の設計例ではこれも省略します。ちょっと省略しすぎかもしれませんが、お許しください。

メモを一覧表示する部分はあまり難しさはないと考えますが、結果的に残るのは、分類のリストからの検索と、新規入力時に大分類と小分類のポップアップメニューがあることです。後者は、大分類と選択すると、それに所属する小分類のポップアップメニューに更新しなければなりません。しかし、この段階では、まず、そうした具体的に実装されるべき機能を把握することに進みます。

[続開発プロセス#4] どこにフォーカスするか

制約された状況での開発プロセスとして、どこにフォーカスするかをまずは示しておきます。開発において、「要求」が最初にあり、それに応じて「設計」「実装」と進む点はもちろん外せません。ここで、重点をおきたい「設計」については、(1)ユーザーインタフェース設計と、(2)内部動作設計の2つに分離して考えます。古くからの言い方だと、外部設計、内部設計に相当し、呼び方としてはそれでいいとは思いますが、ポイントはUIとそれ以外に分離します。(2)は何かいい言葉が見つかったら変えます。

ここで、全体的なデザインやUXはどうなるということが気になるところですが、もちろん、UXはUIとは切っても切れない間柄ではあるものの、本来はUXの検討事項は要求に還元されるのではないかとも言えます。ユーザーの体験は「実現したいこと」であり、どう実現するかと言うことではないのです。

一方、ドメイン知識などはどうでしょう? これは、要求を明確化するための素地と考えます。ビジネスモデルは、要求を明確化したものとも言えます。このように、初期段階の難しいプロセスは、実は要求の定義に帰着します。そうなると、やはり要求は無視できないということになりますが、ここでは現在の様々な開発現場の状況をそのまま取り込むことを考えます。要求分析はしないわけではないですし、軽視するつもりもありません。しかしながら、現実に要求が固まった状況で開発に取り掛かれることは皆無であり、開発途中で要求は変化し、追加され、また物によってはなくなります。開発プロセスの中で、要求までフィードバックして、再検討することは多々あるという状況です。また、派生開発では、謎の実装があってもそれら全部に要求をマッピングすることはせずに進める場合もあるでしょう。時間がないというより、本当に分からないこともあり、影響がないなら無視と判断するのは効率を基準にすれば正しいと言えます。

制約された開発環境の多くは、そうした仕様変更への対処に強いことが特徴として言えます。変更後の実装変更作業が、相対的に軽いと言えるでしょう。そのために制約があるものの、その制約を理解した上で最短のタスクを動かせば、短時間で巻き返しが可能です。そこが大きな特徴であることは明白なのですが、スクラッチな開発の話ばかりが強調されている気もします。

要求自体をどのように扱うかと言う点については、ここで検討する開発プロセスでは、結果的に「通常通り」と言う結論になり、そこから先のプロセスを考えることにします。ただ、制約された開発環境で発生する要求上の問題もある程度は見通しがあるのですが、まずは、その後の工程についての検討から進めたいと考えます。いずれにしても、何らかの方法で、要求を集めてドキュメントにしなければなりません。インタビューの記録や議事録でもいいのですが、それは一次情報なのでそこから整理した要求定義を作文しておくのは、後々のための知識蓄積には必要な作業だと言えます。

ただし、要求定義の段階で、要求抽出をしながらも、設計の検討を始めることで、設計そのものに要求を明確に反映させることも可能です。ただ、設計したらそこに全ての要求が記述されたも同然とはいえません。しかしながら、ある程度の明白な要求は、UI設計をすることでそこに込めることも可能です。UI設計を進めながら要求を検討することで、要求として書き残すことが少なくなるとは言えますが、一方で「書かなくても良い」「書くべき」という判断が難しいところです。

要求が絡むと問題が難しくなりがちですし、そのドキュメンテーションの基準も曖昧な物になりがちではありませんが、最初に要求を追求することは必須であることを指摘しておきます。

[続開発プロセス#1] そして、開発プロセスを再考する

以前に、INTER-Mediatorを中心とした開発プロセスを作るということで、あれこれと記事を書いていましたが、最後の記事からもう3年近く経過してしまいました。開発プロセスとして明白な結果は得られませんでしたが、抽象的に記述することを細部に渡ってやってみて、色々知見は得られたと思っています。もちろん、細部に到ることが抽象化とは反対の方向に向かっているのではないかとか色々考えることがありましたが、その後、しばらく塩漬けにして考えをまとめることにしました。ただ、今も、まだ固まった考えがあるわけではなく、また、別のシリーズとして、書き続けると言うことで、結論に近づければいいなと考えているところです。

まず、以前に書いていた内容は、明らかに粒度が小さすぎます。UIに関しての設計方法は、UIそのものを対象にするのが、直接的であり、そこからわざわざ対象オブジェクトの抽出をして抽象化しても、単に手間がかかるとか、かえってややこしくなるだけではないかと考えました。結果的に、モックアップ駆動開発と言う路線はそのままがいいと言う考えに至っています。

次に、モデルそのものは階層的にすべきではないかという考え方が出てきました。多くの設計ではそうした考え方は一般的です。現状のドメインをモデル化し、それを元に実装可能な形式のモデルをクラス図で描く。ここまでは一般的です。これに加えて、実装可能な設計モデルのコア版、つまりDBスキーマとかなり一致度が高い物を記述する一方、さらに、フレームワークに特有な設計情報を入れ込めた設計モデルを記述するという方法が良いのではないかと考えました。この方法だと、INTER-Mediatorだけでなく、他の環境にも適用ができるでしょう。実際に、FileMakerでもその手法で開発をしてみました。SalesforceやService Nowなど、様々な開発環境を利用する必要がある現在、環境依存とそうでない部分を早い段階で分離することで、実装計画がよりスムーズに進むのではないでしょうか。ローコード系ではとにかくツールにかじりつく蛍光が強いですが、方針を持って作業に入ることがエンジニアリングを実現する手法だと考えます。

モックアップとしてのUIはHTMLで記述します。そして、クラス図を中心にしてドメインモデル、コア設計モデル、実装環境依存設計モデルを作るという方法で設計が進められるということを、しばらくあれこれと書こうと思っています。

「Excelみたいに作ってくれ」という案件が失敗する理由

Excelは悪いソフトではないし、昔から使い込んできただけに、それなりに愛着がある。また、書籍もたくさん書かせてもらって一時はそれで食わせてもらっていたので感謝もしている。しかしながら、Excelの利用技術が結果的におかしな方向に行くのを目の当たりに見てきた。「ネ申エクセル問題」はその集約として非常に良いポイントを突いている。良し悪しを決めつけるのは簡単だが、問題はなぜそのようになり、なぜ是正できないかという分析だろう。「ネ申エクセル問題」としてまとめられた結果、ある領域についての理由と方向性がはっきりしたと言える。

業務システムの開発を請け負っていると、時々、「Excelみたいに作ってくれ」と言われる案件がある。要件がはっきりしていいのじゃないかと思うかもしれないが、これが大きな落とし穴になることもある。なるべく、そのような案件は断るようにしているが、作ってからメンテが大変だったりして、よくよく聞くと、Excelみたいに作ってもらいたかったと思っていたと言うこともあって、顕在化しない場合もある。

ある案件では、これまで、何十人レベルの人たちから毎月Excelのワークシートを提出していたものをWebアプリケーションにして欲しいと言われた。ちょっと複雑な経費精算である。Excelのテンプレートは、おそらく受け入れ側の都合を反映したもので、あまり分かりやすいとは言えないものと感じた。フィールドを全部埋めるのではなく、場合によっては埋まらないフィールドも多く、分類の違うフィールドがずらりと並び、状況によって入力したりしなかったりと言うことを入力者が決めるタイプだ。要するに、第一正規形を満たしていない。

それをそのままWebで作るとしたら、テキストフィールドがずらずら並ぶ。当然ながら、横幅は結構なものになる。状況に応じて必要なフィールドだけを出すようにすれば、スマホでも使えると考え、散々説得したが、「Excelみたいに作ってくれ」というところに常に落ち着く。仕方ないので、「Excelのように見えるだけで動作は違うけどいいでしょうか」と言って、それは納得してもらったはずなのである。

実際にExcelのように作ると言った時、その見かけを2次元セル的にやることと普通は思うかもしれないが、フタを開けると、「Excelのように」が指すポイントが人により異なることが判明した。つまり、これだけの文言では、要求定義にも、要件定義にもなっていない。単なる曖昧な表明にしかなっていないのである。

Webアプリでデータベースだから、レコードを作って入力すると言うのは、あまりに当たり前過ぎることなので、普通に実装したら、「画面を開いたら、最初からワークシートみたいになっているようにして欲しい」と来た。もちろん、そう言うライブラリもあるだろうし、レコードを複数作っておけば済むのだろうけど、ここで受け入れたら、本当にExcelそのものを作らされるのだろうと思って、それはできないと突っぱねた。最初からExcelと同一のものは作れないと言うことは明言し、データベースを利用して作ることも決まっていて、開発費用も決めたので、こちらの裁量がある。こちらとしても、要望が後から来たものは「費用の範囲に収まらない」と言う理由で断れる。そう言うわけで、当然ながら、「レコード追加ボタン」で対応した。

そこで引き下がっていたら、ドラッグしたらコピーするようにとか、式を入れられるようにみたいに要求が留まらないのではと危惧し、前記のような対応を取った。一応、システムは作成でき、想定外のことがあったもののメンテナンス開発でクリアし、今も使用しているようだ。しかしながら、「Excelみたいに〜は要件でもなければ要求でもない」というアンチパターンを実感したと言う意味で、悲喜交々な案件だった。それに、ワークシート的な見え方だと、多分、利用者は保存して添付する手間がないだけで、入力の手間はほとんど変わっていない。保存はないけど、ログインは必要になるので、面倒になったと思う人もいると思う。これは、つまりは今までワークシートを受け取っていた人だけが、集計が楽になるだけという非常に悪い設計の典型のようなシステムでもある。

「ネ申エクセル問題」での大きな教訓は、便利なソフトも使い方によって足かせになると言うことだ。よく、「紙での作業をそのままシステム化しても、効率が上がるわけではない」と言うことも言われる。まさに、ペーパーをExcelに置き換えても同じことが言えるし、それはExcelだけはないだろう。例えば、「LINEみたいなチャット機能もよろしく」みたいな要求は今だといろんな案件で出て来そうだ。しかし、そこで、思考を止めてはいけない。曖昧すぎて、本当に実現したいことが何なのかは、実はそれだけではコミュニケーションできないのである。馴染みのシステムを引き合いに出すのは、要求定義においてはきっかけに過ぎないことを常に意識すべきだろう。