人間のあるべき姿の探索

思索・人形・エンジニアリング

「システム設計のセオリーと実践方法がしっかりわかる教科書」を読みました。

初めに

久しぶりの書評です。こちらの本を読みました。

gihyo.jp

ここ最近、業務や趣味で何かしらのシステムの設計及び実装を行う機会が増えてきたのですが、そこでの課題感として、あるシステムを完成させるためのスコープを明確化する為に、何を設計する必要があるかを知りたかったため、網羅的に書かれているこの本を手に取りました。

構成としては、書籍の内容と、実際のシステム設計に向けた活用の為のイメージについて記載します。また、僕は基本的にコードを記述する人間でもあるので、その点で気になったことも書いていきます。

書評

全体の構成

この本では、10章構成で対象とするシステム設計の位置づけ及びウォーターフォール開発の流れを簡単に説明したうえで、システム設計に必要な設計項目を列挙しています。また、設計にあたって、オンプレ・クラウドの対比やミドルウェア等の設計に影響する考え方についても紹介されています。

設計項目としては、全体設計・入出力設計・データベース設計・ロジック設計・ネットワーク設計・サーバ設計と別れており、さらにその中で具体的な設計書レベルでの設計項目を2~4ページほどで説明する流れになっています。例えば、データベース設計だとデータベース設定やER図、テーブルレイアウト等の項目が紹介されています。

設計項目の分類について

特徴的な考え方として、この本では設計項目を「管理系」「俯瞰系」「個別系」の3つに分類しています。例えば、画面一覧やテーブル一覧は何があるのかを管理するためのもの、システムアーキテクチャ設計やネットワーク全体構成図は全体像を表し、その関係を表現するもの、個別系はそれ以外の処理ロジックや画面レイアウトといった詳細項目となっています。

個人的にはこの考えが気に入っていて、以前電子工作の本で読んだ回路の読み方と似ていました*1。そちらでは、回路を構成する部品の種類、部品ごとの接続関係、部品の設定値(抵抗値等)といった形で捉えており、システム設計一般についてもこれと同様に捉えることができるように思いました。システム設計に特有な点としては、これが木構造のように階層的に詳細化されることや、実はセキュリティ設計の内容がネットワーク設計やデータベース設定に跳ねるといった様に木構造ではなくグラフ構造になっているといった点はありますが、こういった構造を思い描くことでシステムにおいて必要な物事を洗い出すことができるように感じました。

各設計項目の紹介

図解系の書籍の為、左ページが文字で右ページが表・もしくは図を用いた説明となっており、設計書の簡単な具体例を紹介しているページも多いです。紹介する項目がとても多いため詳細に立ち入ることはありませんが、一般的に気を付けるべき物事が記載されているため、参考になる部分は多いと感じました*2

例えば、ネットワーク構成図ではセキュリティの観点で機能は一に問題がないか確認する、サーバ仕様設計では適切なスペックを選択することも重要だが、マシンごとにスペックをカリカリにチューニングすると管理コストが上がることなどが示されています。他にも各設計項目で気を付ける点がアドバイスとして記載されています。

個人的には、性能設計で「実機で動かしてみないと分からない」と断言されていたことが有難かったです。勿論実際のトランザクション数の想定等は大雑把にフェルミ推定のようなことをして試算しますが、テスト環境でも実際に動かしてみることや、本番で思わぬトランザクションの増加が起こることもままある為、まずは試すとか柔軟に設計しておくとか、綿密に計算するよりはそういったある種の切り替えが必要と割り切れそうだと思いました。特に経験の少ない若手の内はセオリーをドキュメントベースで知ることができるとうれしいと感じました。

まとめ

初めに書いたように、システム設計において必要なスコープの把握が目的であり、この本は目的に合致していた為かなり参考になったと思います。そのうえで、システムの構成要素およびその写しとなる設計(物理的には設計書)は階層構造である程度近似できるグラフ構造で繋がっているというのがポイントになっていると感じました。設計を、やっていきたいですね。

個人的な思ったこと

下流から上流への依存関係もある

ウォーターフォール開発を例にとりますが、まず要件定義を行い、そこから全体設計や外部設計を行い、内部設計を行い、実装・テストに…といった流れになると思いますが、この流れは筋がよくないように思いました。設計項目を洗い出して列挙していくと、上述したように各項目の関係は木構造ではなく、グラフ構造になっており、項目ごとの依存関係は双方向になることもしばしばあります。そのため、結局要件定義の段階である程度技術選定に縛られる部分もあるし*3、内部設計をしたら外部設計の方に跳ねることもあり、上から順番に進められるものでもないように思いました。

個人的には、技術のことを分かったうえでより上流と呼ばれる工程に携わることと各設計をサイクルを回すように少しずつ深めていきながら相互依存関係を解消していくべきだと感じました。

設計もする、開発もする、両方やらなきゃいけないのではないか

僕は趣味で個人プロジェクトを立ち上げて10か月ほど設計・開発を行っています。トライ安堵エラーが必要な検証を多分に含むPoC的な要素も多くWBSを引くのも大変な感じですが、その中でプロジェクト管理としてToDoを書き出すと同時に、何を作るべきかということで思いつく項目の設計を書き起こしたりしていました。これをしばらくやっていたことで、実はC#のライブラリでこの手法が使えないからハードウェアレベルで再検討が必要なのでは、とかクラス設計見直した方がよさそうとか設計→実装(PoC)→再設計→実装と繰り返しながら設計をブラッシュアップさせていました。粘土をこねたりBlenderで3Dモデルをこねたりしていたので、そちらの面でもサイクルを回してひたすらブラッシュアップさせていました。

一方業務だと最初の数年はコードを書けるようになって、しばらくしたら設計に手を出したりPMへ…みたいなルートが用意されるイメージがあります。ただ、少ない経験をベースに考えてみると、下流がの設計や実装がこうある場合に上流がこうあるべきといったことは考える必要がありますし、逆に上流でこういう設計をした場合にどのような詳細設計・実装になるかイメージすることで全体への理解が深まると思います。

これは一般的な上記キャリアパスのイメージだと経験するのが難しいように感じます。理想的には、大雑把なレベルでもよいので、設計もやる、開発もやる、みたいな練習ができるとよいのではないかと感じました。実際には業務レベルだとそれをやらせてもらえる機会がないので、趣味で試したり机上設計の練習を自主的に申し出たりする必要があるのかなと思いますが。

大きなシステムになると難しいですが、要件が出てきたときにその実装がパッと浮かんで、そこにかかる実装コストや運用における課題、金額等が浮かんでくるようになると良いなと思っています。しばらくコードを書いていて思ったのですが、結局プログラムを書けるだけではいけないんですよね。例えばあるユーザーが購入した商品の合計金額を算出するAPIを一本立てたい、となった場合に、フレームワークとしてASP.NETを用いて3層アーキテクチャでコードを書いていれば、コントローラーにAPIを一本立てて、インフラにSQLクエリもしくはEntityFrameworkを用いたクエリコードを記述して、ビジネスロジック層にそれらのつなぎになるロジックを組み立てていきます。しかし、toCで一般ユーザーの認証を実装したいといわれた場合には一からコードを組み立てるのは現実的ではなく、外部認証サービスを利用するのが現実的な選択になり、それらの選定及び設定値を決めたうえで、プログラムとしては各認証サービスに則った処理を追加することになります。

結局機能要件と非機能要件を共に満たすには、システムを構成する要素を完全に理解した上でどこで担保するのが一番合理的か考える必要があるので、実際に担当するスコープは少しずつ広げていくにしても早いうちから俯瞰する機会を増やして知っているシステムのパターンを増やしていくことが設計・実装をやっていくうえで役に立つのではないでしょうか。

*1:こちらの本はまだほとんど読めていないので電子工作は何もわからないです

*2:現場の知識が役に立つことは言うまでもないですが

*3:そもそもシステムの運用コストについては見積もり段階である程度サービスの選定が必要になるので…