今回はアプリケーションの基本設計を行っていく。
 第1回でまとめた要件定義の内容を簡単な図にしてみると、

アプリケーション設計

──こんな感じになる。処理の流れとしては、フロントエンド側のページ(UI)は「Vue.js」と「Vuetify」で作成・制御される。そして、ページ内で発生したユーザーからの要求は「Axios」を使って非同期でバックエンドに送信する。バックエンド側では、「PHP 8」でユーザーのリクエストを処理して、必要があれば「MySQL」データベースに問い合わせを行う。データベースの応答結果は、再び「PHP 8」で最適化され、「Axios」のレスポンスとして返信する。返信されたレスポンスは「Vue.js」と「Vuetify」でUIへ適用される。
 まぁ、今では一般的なWEBアプリケーションの建付けなので、あまり特筆するべきものはないんだよね……。

 開発規模の小さい今回のような趣味的なツールであれば、アプリケーション設計はこれだけでもさほど困らない。しかしながら、一般的な開発では、これだけだと設計としてはあまりにも抽象的で、開発着手するには情報が少な過ぎるだろう。
 では、アプリケーションの設計フェーズでは他にどのような成果物が期待されるのかを紹介していこう。

システム設計

 開発するアプリケーションの設置する場所や環境の設計のことだ。どういう形式でアプリケーションを提供するのかによって設計内容は大きく異なる。サーバが必要であれば、ベンダーを選定し、ネットワーク構成を決め、各サーバの設定や用途を定義するなど、およそインフラ周りの全てを設計書としてまとめる。
 この設計周りは、大抵は開発系エンジニアではなくネットワークエンジニアが担当することになる。開発側からはアプリケーションで取り扱うデータ量と、見込まれるフロントエンド側の負荷、採用を予定している要素技術(DBはMySQL、WEBサーバはNginx、言語はPHP、node.jsなど)等をあらかじめ伝えておき、準備すべきサーバのスペック等を両者で詰めていくのが理想である。
 私の経験上、何気に同一社内でも開発系とネットワーク系のエンジニアが分断しているケースがままあるので、共同歩調を取るには、どちらのエンジニアとも日頃から仲良くしておくと困らない。
 ちなみに、今回の開発では既に使用しているWEBサーバ/データベース内に追加する形になるので、改めてシステム設計をする必要はない。

データベース設計

 すでに前回実施したアプリケーションで取り扱うデータモデルの設計である。データベースを利用するかどうかに関わらず、取り扱うデータがあるアプリケーションであればそのデータの仕様を取りまとめておくことが必要になる。
 この設計についても、私の経験則上、データベースに強いエンジニアに依頼することが多いように思われる。本来であれば、実際に処理を開発するエンジニアがひな形を作り、データベースに詳しいエンジニアが監修するような体制が理想的である。

画面設計

 対人向けのユーザインターフェース(UI)が存在するアプリケーションの場合、この画面設計が必要になって来る。この画面設計には、アプリケーション全体の画面遷移の概要を説明する「画面遷移設計」や、各画面ごとのコンポーネント配置を説明する「構成要素設計」、見た目の画面レイアウトを定義する「UI/UXデザイン」などの設計書がある。これらの設計については、WEBデザイナーに依頼されることが多いが、デザインのひな形になる「構成要素設計」や「画面遷移設計」などはシステム全体を把握しているエンジニア側から提示してあげる必要があるだろう。
 また、この部分の設計書はメンテナンスが大変な文書化を行うよりも、モックアップとして作成してしまうという手段もある。デザイン関連の設計って、何気にステークホルダー間でのイメージの共有化がしづらいので、実際にモックとして作成して、レイアウトや、コンポーネントの動き、画面遷移まで確認してもらい、承認を受けたモックアップデータそのものを成果物にしてしまう方が効率的なのだ。
 今回の開発でも、画面設計についてはモックアップをベースにして進めていくので、詳しくはモックアップ作成の回で説明する。

インターフェース設計

 これは、外部連携用の仕様を定義するものだ。開発するアプリケーションが自己完結型ではなく、他のサブシステムや、外部APIと接続を行ってデータのやり取りをするようなモノだった場合、ここでそれらの連携仕様を設計していく。
 例えば、各種決済連携や、SMS利用による二要素認証などだ。これらは、連携先のシステムにAPIが準備されているのであれば、API仕様に応じたデータを自前のアプリケーション側から送出して、応答を取得できる仕組みを作らなければならない。APIがない場合だと、メールで連携する(空メール等)・データファイルをFTPする(帳票系システム等)・スクレイピングするなど、連携方式は連携先に応じて様々である。

業務・運用設計

 こちらはちょっと毛色が違って、開発が完了してアプリケーションがリリースされた後に発生する業務の設計だ。例えば、完成したアプリケーションを運用するWEB担当者向けの「操作マニュアル」や、各種ログのローテーション仕様、定時バッチ処理のスケジューリング、システム・メンテナンスやバージョンアップ等の中長期的なスケジュールなどが含まれる。
 これらは初期の設計フェーズから漏れても開発フェーズにインパクトがないので、設計後の開発や試験フェーズあたりから同時並行的に進捗されることもある。

処理設計

 「内部設計」や「詳細設計」とも呼ばれる、開発するエンジニアにとって重要な、実際の開発方式に関わる設計だ。コーディング規約の策定や、処理フロー、クラス定義、I/O設計、CRUD設計など、必要な設計は多岐に渡る。この設計をどの粒度まで行うかによって、開発フェーズ後における完成度に如実に差が出る。
 ただし、個人的には、この設計に時間をかけるのは非効率だと思っている(有益ではあるのだが)。クライアント側から納品物として「詳細設計書」を求められない限りは、こんな設計文書は作らず、さっさとコードを書き始めた方がいいと思うのだ。今時なら、コード内にメタ情報としてドキュメント的な仕様を書いていける(PHP 8ならアトリビュート、PHP 7以前ならPHP Doc等、JavaScriptならESDoc等)ので、もし必要ならコーディング後にそれらを詳細設計書として出力してしまえば事足りるのではないだろうか。
 確かに、きちんと設計してから作った処理は、不具合が少ないし、見やすいし、処理同士の連携もスムーズだ。しかし、この設計に時間を費やすと、プロジェクト全体のスピード感は失われる。もしも、失われたスピード感が、優れた処理設計によって、後続の開発フェーズと試験フェーズの工期短縮を促進してくれるのであれば、処理設計に注力すべきだろう。でも、私の経験則上、そんなケースに巡り合ったことがない。しかも、実務案件で設計フェーズに潤沢な時間が与えられるようなケースもまれなので、そんな切迫した状況下で優れた設計を行えというのがそもそも矛盾している。たとえ、重厚長大な詳細設計書を書き上げたとしても、クライアントは納品時点ではほぼ読んでくれないし、役に立つのは、せいぜい不具合が発生した際に処理仕様を調べる時ぐらいではないだろうか……(やばい、だいぶ毒気づいて来たな)。

 私のように設計自体は好きだけど、設計書のドキュメンテーションは面倒だから好きじゃないというエンジニアは多いと思うが、そういう人にも強制的に設計を出させる開発方式もある。「テスト駆動開発(Test-Driven Development: TDD)」だ。これは、ある処理を開発する前に、その処理の動作テスト(ユニットテスト)を書くという開発方式で、処理設計と実開発の行程を分断せずに、書かれた動作テストをその処理自体の設計書に転用しやすいというものだ。一時期、私もこれをやっていたが、テスト書くのが非常に億劫なことと、全体の開発スピードがやたら落ちることから、最近はやっていない。処理が複雑になってくると、スタブとかモックとかを準備しなくちゃテストができないこともあり、なんかテストのためのコーディングを延々と繰り返していたら、「あれ、結構コード書いたけど、作らなきゃいけない本体を作ってないじゃん」って、途方もない疲労感に襲われたからだ。気分的にあまりやりたくない開発方式なんだが、開発手順としての有効性は抜群に良いので、個人的な開発をする時でも、これをやるかどうかいつも悩んでいる。

 ちょっと話が逸れるが、オープンソース界隈を歩いていると、カオスなコードに出会うことが結構多い。その後、プロダクトのリリースを継続してウォッチして行くと、どんどん洗練されたコードになっていく。世に出たアプリケーションは、使われる人たちによって改善を促され、それが作者のエンジニアとしてのレベルアップに繋がり、日々新たな技術が登場することによって、どんどん効果的で優れたコードにブラッシュアップされていくのだ。設計はあるに越したことはないが、アプリケーションが実現しなければならない根本の目標を達成できさえすれば、そこまで気にせずにカオスなコード書いてもイイのではないだろうか。
 真摯に設計に取り組んでいるエンジニアの方々には失礼千万なことは承知のうえであえて云わせてもらえば、設計を重要視する論調って、私にしてみればプレイ中の失敗を恐れるあまり、前もって言い訳を用意している偽善的なポーズに思えるのだ。よくメイド・イン・ジャパンのプロダクトの生産性が劣悪な理由の一つに、こういう「手順」や「セオリー」にあまりにも囚われ過ぎて、最初に完璧を求めすぎるからだと揶揄されるが、その縮図こそが、プロダクト開発シーンの設計フェーズの在り方にあるように思うのだ。
 ぶっちゃけ、初めて世に出すバージョンは「動きゃイイじゃん!」というのが、私の持論である(その後、継続的にリファクタリングしていくのが大前提になるんだけどね……)。

 閑話休題、業務でシステム開発している方々からはだいぶ批判を受けそうでもあるので、処理設計の一般論についてはここまでにしておく(笑)
 今回開発するアプリケーションは私一人で製造するモノでもあり、事前に処理設計をして第三者的な目線からアドバイスを貰えるものでもないので、スキップする。ただ、せっかくPHP 8を使うので、アトリビュートで各処理にメタ付けだけはしておこうかと思っている。 

試験計画

 テスト設計とも呼ばれる。一般的に、単体テストは含まず、開発がひと段落した後の結合試験の計画になる。テストスケジュールの策定や、テスト項目表・テスト成績表などの作成が含まれる。ぶっちゃけ、前述の処理設計をすっとばしても、この試験計画が入念に作成されていれば、プロダクト全体の完成度を向上させられる(改修フェーズが増えて試験フェーズが長引く可能性はあるが)。かといって、この試験計画をおざなりにすると、いくら優秀な設計を元に開発されても、プロダクト全体の完成度は低下することは覚えておく必要がある。
 あと、忘れがちなのがセキュリティ試験と負荷試験だ。どちらもインフラの設定等にも絡んで来たりするので、関係各位と協力して試験を行っておかないと痛い目を見る。特に、正式運用後に想定以上のデータ量によるシステムパフォーマンスの低下などが発生すると、サービスに対しての信頼性が失墜して、最悪サービス自体が潰れることにもなりかねないのだ。

マスタースケジュール

 上記の他にも、設計書と呼ばれる文書は枚挙にいとまがないが、それらすべての作成工期等を含んで、プロジェクト全体の行程をスケジュール化したものが、マスタースケジュールである。マスタースケジュールの各工程には、リスク管理として費用の許す限り、バッファーを積んで置く必要がある。
 このスケジュール策定や実際の管理を行うのが、プロジェクト・マネジャー(PM)と呼ばれる職掌の人で、この人はプロジェクトにおける全貌を常に把握しておく必要がある。つまり、その人に訊けば、プロジェクトのことは何でもわかるという体制にしておくことが重要だ。

 今回はここまで。
 私個人の嗜好や意見がふんだんに盛り込まれた内容になっているので、一般的な業務フローにはそぐわないケースも多々あるかと思う。
 くれぐれも、

PM「あまり時間が割けないんですが、詳細設計お願いしますね」
エンジニア「もちろんです……」
エンジニア「だが断る」
PM「ナニッ!?」

──という、岸部露伴的なやりとりは控えよう(笑)

 いやはや、業務として開発に携わると、ホント色々と制限がかけられてしまってなかなか「楽しい」コード製造のフェーズに入れないのが常だ。だからこそ、趣味で開発を行う時ぐらいは、自由に、とことん楽しんで作りたいものだ。得てして、そうしたストレスのかからない環境で作ったアプリケーションこそが、バズったりするもんだから、世の中って皮肉なもんである。

 さぁ、次回は早速、開発着手だ。PHPでデータベース操作周りを作っていくよ。