本記事は『はじめての設計をやり抜くための本 第2版 概念モデリングからアプリケーション、データベース、アーキテクチャ設計、アジャイル開発まで』(吉原庄三郎)の「第2章 設計の目的」から一部を抜粋したものです。掲載にあたって編集しています。
何を設計するのか
設計ができるようになるには、設計とは何かを知る必要があります。世の中には、設計に関する書籍がたくさん出回っています。最近では、オブジェクト指向設計に関するものが多いようです。書店に行くと、「オブジェクト指向」「UML」「ユースケース」といった文字が目に留まります。他にも、「アーキテクチャ」「デザインパターン」「フレームワーク」などもよく見かけるでしょう。これから設計を学ぶ皆さんは、学ぶことが多くて大変だと思うかもしれません。
設計ができるようになるには、設計がわかっているだけでは足りません。ハードウェアやネットワーク、OS、ミドルウェアなどの幅広い知識が必要です。確かに、HTTPの意味がわからなくても、HTMLとPHPがわかっていれば、ある程度のWebシステムを開発することはできるでしょう。しかし、それは動くだけのシステムであり、実用に耐えられるようなパフォーマンスやセキュリティ、機能を満たすことは難しいはずです。だからといって、焦ってはいけません。幅広い知識を身に付けるには、基本が必要です。
すでに述べたように、設計とは広い意味を持つ言葉です。私たちは一体何を設計するのでしょうか? 設計とは何かを知る前に、何を設計するのかを整理しましょう。
設計の対象
コンピュータの世界で設計といった場合、さまざまなものが対象となります。例えば、
- システム設計
- ソフトウェア設計
- アプリケーション設計
- ネットワーク設計
- データベース設計
- アーキテクチャ設計
- 移行設計
- 運用設計
などが挙げられます。
これらの意味と、それぞれの違いがわかるでしょうか? 必ずしも標準的で明確な定義があるわけではありません。ここでは、一般的に使われる定義を紹介します。
まず、システム、ソフトウェア、アプリケーションという用語に着目します。この中では、システムがいちばん大きな概念です。システムは、ネットワーク、ハードウェア、ソフトウェアを含めた、何らかの価値を提供する仕組み全体を指します(図2-1)。
システムの構成要素を図2-2のようなスタックで表現してみます。スタックは、下から上に積み上げられています。下に行くほど低レベルな基礎技術です。上に行くほどシステムの利用者にとって付加価値の高い機能を提供す る技術です。
下層のネットワーク設計では、購入するネットワーク機器やハードウェア機器をどのように構成するかを検討します。本格的な企業システムでは、機器を販売する会社に構築を含めて依頼することが多いでしょう。ハードウェアの選択と同時にOSも選択することが多いので、下層の3つ、すなわちネットワーク、ハードウェア、OSをあわせてインフラ設計と呼ぶことがあります。
インフラとはインフラストラクチャの略です。図2-2にはハードウェア設計がありません。ハードウェアは、メーカーの出荷時に完成されているので、設定(コンフィグレーション)することはあっても設計することはないからです。その意味で、図2-2はシステム開発会社にとってのスタックとなります。
最近ではインフラとしてクラウドが活用されています。クラウドの主要なものとして、AWS(Amazon Web Services)、Microsoft Azure、Google Cloud Platformなどがあります。クラウドを利用すればハードウェアを購入する必要がありません。ハードウェアはクラウドベンダーが管理するデータセンターにあり、インターネットなどのネットワーク経由で接続します。ハードウェアはすべて仮想化されて利用者からは意識することはできません。
クラウドに対して、従来のハードウェアを運用することをオンプレミスといいます。クラウドの主な利点は、ハードウェアを購入する必要がないので初期費用を抑えられることや、仮想サーバーの増設や仮想ディスク容量を増やすことが容易でスケールアップやスケールアウトが簡単に行えることです。サービスによっては自動的にスケールアップしてくれるものもあります。オンプレミスでは大変だったサイジングがとても楽になるのは魅力です。
クラウドの欠点は、クラウドベンダーの都合で仕様が変更されることや、サービスが停止することがあることです。また複数の利用者が同じ環境を利用することもあるので、他の利用者が負荷をかけるとサービス全体の性能が落ちることもあります。
大事なことはクラウドを利用するとしても、システムのスタックの考え方は変わらないということです。クラウドになってもインフラ設計は必要であり、OSやサーバーやネットワークの知識がなければ設計できないということです。
インフラの上には、データベース、ミドルウェア、アプリケーションがあります。データベース設計には、データベース製品の選定やデータベースファイルの設計、データベースのテーブルの設計などが含まれます。これらの設計では、要件を満たすためのパフォーマンスやサイジングを考慮します。
最近では、システム開発にミドルウェアを利用することが当たり前になりました。ミドルウェアとは、Webサーバー(Apache HTTP Server やnginxなど)やWebアプリケーションサーバー(TomcatやJettyなど)、ビッグデータのための分散コンピューティングのApache Sparkなどです。クラウドがミドルウェアに該当するものをサービスとして提供することも数多くあります。
AWS Lambdaはサーバレスコンピューティングのためのインフラと統合されたミドルウェアに位置付けられると考えられます。ミドルウェアの役割は多岐にわたりますが、いずれも多くのアプリケーションで必要になるような基本的な機能を提供します。具体的には、HTTPのようなネットワークプロトコルの実装、マルチスレッド管理、データベース接続を含めたトランザクション機能などを提供します。
ミドルウェア製品は、ミドルウェアメーカーの出荷時に完成されているので、設定(コンフィグレーション)することはあっても、ミドルウェア自体を設計することはありません。
アプリケーションは、システムの利用者にとって付加価値のある機能を提供します。図2-2に示したミドルウェア以下のスタックは、何らかの既製品を購入して設定や構成をすると動作します。アプリケーションも、ERP(Enterprise Resource Planning)のようなパッケージを利用することもできれば、ゼロから開発することもできます。パッケージによっては、ミドルウェアやデータベースを内部に持つものもあります。
データベース、ミドルウェア、アプリケーションの設計を総称してソフトウェア設計と呼びます。ソフトウェア設計にOSを含めることもありますが、前述したとおり、OSはインフラ設計に含めるのが通常です。本書のテーマである設計の範囲は、この「ソフトウェア設計」です。
スタックとプロダクトの関係
図2-3に、設計の範囲とそれをカバーするプロダクトの一例を示します。これをもとに、スタックおよび設計の意味を確認していきましょう。
アプリケーション設計
まず、いちばん上のアプリケーションは、皆さんが開発する部分だったり、特定の業務パッケージだったりします。これはさまざまなので、図2-3では空欄にしています。
アーキテクチャ設計
アーキテクチャという言葉は、「設計の基本構造」という意味です。したがって、さまざまなものにアーキテクチャがあります。ネットワークにも、ハードウェアにも、OSにも、データベースにも、ミドルウェアにもアーキテクチャはあります。
ただ、これらのアーキテクチャには、アプリケーションを開発する側はあまり関心がありません。各プロダクトのメーカーの人や、組込みシステムのような低レベルなプログラミングをする人にとっては重要ですが、アプリケーションの開発者にとっては興味の対象ではないのです。アプリケーションの開発者にとって重要なのは、次の3つのアーキテクチャです。
- アプリケーションアーキテクチャ
- ソフトウェアアーキテクチャ
- システムアーキテクチャ
先ほどのスタックに照らし合わせると、図2-4のようになります。本書が対象とする範囲は、このうち「ソフトウェアアーキテクチャ設計」です。
低レベルのアーキテクチャ
厳密にいえば、現在でもハードウェアのアーキテクチャにソフトウェアの設計は影響されます。32ビットCPUであれば4GBまでのメモリしか理論上は使えません。昔の16ビットCPUであれば64KBまでのメモリしか理論上は使えませんでした。実際には、OSによって拡張が行われ、16ビットCPUでも1MBまでメモリが使えるようになっていました(こんな話は飲み会の席で先輩から聞かされているかもしれませんね)。
今でも、ファイル操作や、ネットワークに関する処理を記述する場合は、Javaのようなマルチプラットフォームの言語でも、どのプラットフォームで動作するシステムなのかによって気を付けるべきことがあります。例えば、ファイル操作であれば、WindowsとLinuxではファイルロックの取得方法と効果が異なります。
ハードウェアやOSはスタックの下層にあるので、低レベルのアーキテクチャと呼ばれます。OSやミドルウェアやプログラミング言語の進歩により、低レベルのアーキテクチャを意識することは減りましたが、これらの低レベルのアーキテクチャを知っていることは、設計者にとって重要です。CやC++のプログラマにとっては、今後も必須の知識です。インテルの8086系(現在のPentium系)CPUの原理や、Linuxのファイルシステムなどについては、ぜひ勉強するとよいでしょう。
移行設計
設計とは、システムを開発するためだけに必要なものではありません。開発したシステムを本番環境に移行する際にも、設計が欠かせません。この設計を「移行設計」と呼びます。
移行設計は、開発が完了したシステムを既存システムに代わって本番環境で動作するように配置し、データなどを準備するための設計です。新しくシステムを開発した場合には問題になりませんが、稼働している既存システムがあり、あるタイミングで既存システムから新システムに動作を切り替える場合には、移行設計を入念に検討する必要があります。本書のテーマはシステム開発のための設計なので、移行設計については詳しく述べませんが、ポイントだけを簡単に説明します。
移行作業は非常に難しいものです。既存システムへの影響を最小限に留めながら、本番環境に新システムを配置し、サービスインと同時に正常に動作するようにします。いちばん難しいのは、データベースに格納されているデータを移行することです。既存システムが直前まで動いている場合は、その最新のデータを新しいデータベースにインポートすることになり、この操作にミスがあるとデータが消えてしまったり、間違ったデータが本番環境のデータベースに入ってしまったりといった致命的な状況になることがあります。本番データは量が多いので移行の時間もかかり、ミスを挽回する時間も多くはありません。この移行作業の手順を検討するのが移行設計なのです。
移行設計でも、スタックの考え方が利用できます。当然かもしれませんが、スタックの多くの構成が変わらなければ、移行作業は簡単に済みます。また、変更がスタックの中に閉じていれば、影響も少なくなります。例えば、ネットワーク、ハードウェア、OS、データベースの構成が既存システムと同じであれば、アプリケーションとミドルウェアだけを新しいものに移行し、データベースはデータだけを移行すれば済みます。データベース製品のバージョンやテーブルの構成などが変わらなければ、データの移行も大きな問題なく完了できるでしょう(図2-5)。
データベースのテーブルの構成を変えなければならない状況もあります。テーブルやカラムが追加になるだけならよいのですが、カラムの名前や型が変わったり、カラムがなくなったりすると、移行は簡単ではありません。その場合は、移行プログラムを作成し、プログラムでデータを加工しながら新しいデータベースに登録していきます。移行プログラムにもさまざまな方式があり、一度にすべて移行するものや、段階的に移行するものがあります。
移行プログラムを開発するのは、方法としてはベタですが、これが一般的なやり方です。それ以外にもデータベースのレプリケーションを作成したり、既存システムを使って、新旧両方のデータベースに書き込ませたりする方法もあります。新旧両方のデータベースに書き込ませるには、改修が必要となります。
どのような移行方法を選択するかは、そのシステムの使われ方や稼働状況によって決まります。移行作業には、実際にリハーサルをやってみないとわからない問題があるものです。できるだけ本番に近い環境で、何度もリハーサルを行いましょう。移行作業時間を計測し、移行作業手順を見直しましょう。
運用設計
移行設計の次は、運用設計です。
運用設計では、移行が完了したシステムをどのように運用するのか、障害が発生した時にどのように対処するのかを設計します。トランザクションとデータの整合性や、フェールオーバーのためのクラスタリング、身近なところではログの出力方法など、ソフトウェア設計と運用設計が密接に関連する部分があります。
この運用設計も、本書の説明範囲ではありませんので、ソフトウェア設計と関連する部分を中心にポイントだけを説明します。
システムの運用は、「正常運転→障害対応→フィードバック」のサイクルで行われます(図2-6)。それぞれの段階で主に行うことは、表2-1に示すとおりです。
運用設計の中で、ソフトウェア設計と関係が強いものを次に示します。
- 障害を監視するためのログ出力、ヘルスチェック方法の提供
- フェールオーバーのためのクラスタリングなどのシステム構成
- バックアップおよびリカバリーを行うためのミドルウェアやデータベースの選定
- リカバリーを行うためのデータの完全性を保つ設計(トランザクション、バックアップファイルなど)
- 障害を分析するためのログ出力、システムダンプの提供
- 簡単な起動・停止方法の提供
多くのシステム開発では、運用設計は開発プロジェクトの後半で行われます。開発プロジェクトの前半は、要件定義や設計で忙しいこともあり、要件定義や設計が終わらないとどのようなシステムになるのかがわからず、運用設計を行いにくいのが理由です。しかし、前述したようなソフトウェア設計に密接な運用設計の観点もあり、これらがソフトウェア設計が終わってから検討されるのは良くありません。できればソフトウェア設計が完了するまでに、運用設計の中でソフトウェア設計に関連する部分だけでも検討するようにしましょう。
以上が、システム開発会社の視点で見た時の、システム開発に関する設計についての説明です。また、その中から本書で扱う「設計」についても説明しました。繰り返しますが、本書で扱う設計は次の2つです。
- ソフトウェア設計
- ソフトウェアアーキテクチャ設計
さらに、どのような用途で使うシステムなのかによって、設計方法も変わってきます。組込みソフトウェアとクライアント/サーバー型、クライアントアプリケーションとWebアプリケーションでは、基本的な設計の考え方は一緒でも、具体的な手法までは同じではありません。本書では、ある企業の業務用のWebシステムを開発することを前提に、設計の実践的な手法を説明していきます。