ソフトウェア開発に関する書籍をいくつか読んだのでまとめてみる

2022-11-23
2022-11-23

ソフトウェア開発に関して復習もかねてちょっと広い視点からの整理と感想をまとめてみました。

以下が今回読んだ(参考にした)書籍たちです。全部を詳細に読みこんだわけではなく、過去に一度読んだものも含みます。

本記事はオレオレまとめなのであくまで参考程度と考えてください。

そもそもソフトウェア開発はどう行われるか

ソフトウェアには当然ソフトウェアを使う人がいます。その人たちは何らかの目的・要求があり、それらの目的・要求を実現するためにソフトウェアを使いたいと考えています。

ここでは簡単のためソフトウェアを使いたい人を顧客と表記します。

顧客は自分たちではソフトウェアを作れないので、ソフトウェア開発専門の人たちにソフトウェア開発を依頼します。

ここにきてソフトウェア開発者が出てきます

ここからは開発者がどのように顧客の要望するソフトウェアを開発するかになります。

まず開発者は顧客が要望するソフトウェアが、どのようなものか具体化していく必要があります。この作業がいわゆる要件定義です。

要件定義では、顧客が要求する事項を実現するために必要な機能や性能(機能要件、非機能要件)を定義します。 顧客はソフトウェアの専門家ではないので、顧客の要求は開発者にとっては抽象的すぎる、そして顧客自身も本当に自分たちが欲しいものを言語化できてない可能性が高いです。 要件定義で顧客が本当に欲しいものを聞き出す、そしてそれを実現するために必要な機能、非機能を正しく洗い出せるかが重要です。

例:

  • 顧客:家計簿アプリが欲しい
  • 開発者:スマホアプリ、ブラウザ?、外部との連携(銀行やカード)はある?、家計簿への入力方法はどんなものが必要?、通知やグラフはどんなものが必要か、etc...

要件定義ができたらが次は設計・実装・テストに移っていきます。

この要件がある程度固まった後にどのように開発を進めていくかは開発チームが採用している開発プロセスに依存します。

要件定義で行う内容・呼称・成果物に多少の違いはあるかもしれませんが、どんな開発プロセスでも似たようなことは行うはずです。

開発プロセスたち

どのように開発を進めていくか、つまり最終的に顧客が望むソフトウェアを作るためにどのような手順を踏むか考える必要があります。

パッと思いつくのはウォーターフォール(WF)開発とアジャイル開発でしょう。

WF 開発とアジャイル開発の違い

いくつか書籍を読んでみてわかったのは、 WF 開発とアジャイル開発の対比で重要なのは開発の進め方であるということです。

言いたいのは、アジャイル開発であっても WF で実施した工程は必要になることもあり、成果物に関しても同様のものが必要になる可能性があることです。 WF では最終成果物(つまり完成したソフトウェア)を 100%完全に予測・設計ができたとして実装・テストをしますが、 アジャイル開発では全体の 1%(100 個機能があるうちの 1 個)を設計・実装・テストまでやってしまい、フィードバックをもらい必要があれば改善し、できたらまた次の 1 機能というように細かく WF のサイクル回しているようなイメージです。

アジャイル開発の方がいいのか?

一概には言えませんが、多くの場合アジャイル開発の方が開発者には現実的なのかなと思います。 理由として、WF 開発で事前の要件定義と設計で漏れなくいけるとは考えにくいからです。 実装・テストをやってみてひっくり返ることは十分考えられます。

それであれば、最初からソフトウェア開発は不確実性の高い作業だということを認め、ちょっとずつ確認しながら進めていきましょうよ、とした方が開発者としては現実的だと思ってしまいます。

逆に大きな不確実性はないとある程度自信を持って言える状況、似たような要件で過去に何度か開発した、期間が短すぎてできることがそもそも少ない、などの場合であれば WF でもいいかもしれません。

いずれにせよ両者の違いとトレードオフを理解し、適した方を採用するという判断力が必要です。

要件定義から設計へ

必要な機能がわかれば次はいよいよ設計です。

設計で考えることはソフトウェアアーキテクチャです。

ソフトウェアアーキテクチャの定義は以下の通りです(「ソフトウェアアーキテクチャの基礎」より引用)

  • システムの構造
    • マイクロサービス、レイヤードなど
  • アーキテクチャ特性
    • 可用性、スケーラビリティなど
  • アーキテクチャ決定
    • システムをどのように構築するかのルール
  • 設計指針
    • どう実装を進めいてくかのガイドライン

定義が箇条書きになってるのに違和感を覚えるかもですが、ソフトウェアアーキテクチャの定義はそれだけ人によって解釈が多岐にわたっているのです。 (この定義の詳しい背景と内容は「ソフトウェアアーキテクチャの基礎」の第 1 章に記載されています)

アーキテクトと呼ばれる人が上記 4 つをどのように選択していくかを考える必要があります。

設計を考えるのは難しい

個人的にここが一番ハードルが高いです。

設計するアーキテクトは顧客要求(要件)の理解、実装に関する技術的な理解、対象ドメインの理解など多くの事柄を理解し、総合的にベストな決定を行う必要があります。

「ソフトウェアアーキテクチャの基礎」でも書かれてましたが、アーキテクトはかなり広範な知識が要求されます。

システムの構造一つとってもそんなにたくさん候補が出てきませんし、経験もないです。

ドメイン駆動設計(DDD)はどう位置付けられるか

「セキュア・バイ・デザイン」や「ソフトウェアアーキテクチャの基礎」でも頻繁に言及されるのがドメイン駆動設計(DDD)です。

ここでは DDD に関して細かく説明しないので、詳しい定義は書籍等を参考にしてください。 ドメイン駆動設計は、端的にいうとソフトウェアで解決したい問題領域をどう実装に落とし込むかという設計手法です。

DDD がソフトウェア開発の中でどう位置付けられるかですが、おそらく要件定義から実装に入る手前(設計)のドメインエキスパートとドメインモデルを定義するところと、得られたドメインモデルをどう実装に落とし込んでいくかの 2 箇所に大別されそうです。

調べてみると DDD 自体はわりといろんな要件に適用できそうです。 そう考えると DDD はソフトウェアアーキテクチャにおいて比較的幅広く使えるテクニックと言えます。

ソフトウェア開発におけるテスト

ソフトウェア開発に携わっているとテストに関する話題は事欠きません。

では実際にどのようなテストが存在し、開発全体の中でどうテストを取り入れていくべきかを考えたいと思います。

テストには以下のようなものがあると思います。思います、という言い方にしたのは、書籍によって名称が違ったりするので正確な表記、内容に自信がないからです。

  • 単体テスト(ユニットテスト)
    • 関数やクラス単位ですのテスト
  • 結合テスト(統合テスト)
    • 複数の関数にわたる動作のテスト
    • データベースなどが絡むと結合テストに該当すると思ってる
  • システムテスト(総合テスト)
    • 実際の使われ方を想定したテスト
    • 要件定義で書かれた内容が正しく実行できるかを確かめる
    • システムテストの中に以下のようなテストも含まれる
      • パフォーマンステスト
        • レスポンス時間や処理速度が想定通りの範囲で推移するか、もしくは許容オーバーの際に正しくハンドリングされているかをみるテスト
      • セキュリティテスト
        • 文字通り
  • 受け入れテスト
    • 顧客側が要求仕様通りのシステムができたかチェックするテスト
  • 回帰テスト
    • 新しい機能や修正が追加された際に既存機能が正常か確かめるテスト
  • 探索的テスト
    • 人が探索的にソフトウェアの穴となりそうなところをテストする

上記は WF 開発で実施されるテストがベースになっています。

アジャイルでは一つのバックログ(ユーザーストーリー)単位で単体テストからシステムテストに近い内容を実施し、顧客にみてもらう(受け入れテスト)をサイクルの中で実施することになると思います。 アジャイル開発で行う場合は、アジャイルテストの 4 象限なるものがあり、それを参考に実行されることが多いようです。

アジャイル開発の場合はテストの自動化が結構大事になるはず。なぜなら、完成した機能に対してどんどん新しい機能を追加していくことになるので、受け入れ済みのところが壊れていないことを担保する必要があります。 また明示的なシステムテストフェーズなどを設けない場合は、セキュリティやパフォーマンステストも随時やらねばなりません。

じゃあどこからどこまで自動化するのかということを考えます。まず単体テストレベルは間違いなく自動化の対象です。実行も簡単で他との依存関係がほぼないはずなので簡単に実行できます。

問題は結合テストレベルですが、これもアジャイルでやるなら自動化対象かなと個人的には思います。理由は先ほど述べたとおりで DB や他モジュールとの関連した動作も合わせてテストで保証しておかないと追加の機能を実装しづらいからです。 ただ、UI テストレベルの自動化ではなく、あくまでバックエンドの機能レベルの自動化です(UI テストは保守性が悪く、書くのも大変なため)

ただここで問題になるのは、DB や他システムが絡むような複雑なテストは書くのに時間がかかり、開発生産性を落としたり、保守性が悪くなったりしがちです。うーんここに関して具体的に書籍で言及してるのをまだ探せてないです。

感想・まとめ

大枠の整理はとても良い勉強になった。実際、書きながらわからないことがボロボロ出てきたので、書籍を見直したりネットで検索したりをずいぶん繰り返した。

一方で、アジャイル開発におけるテストのやり方についてはまだ理解しきれていない。 テストの厚さはぱっと見だと WF の方がしっかりしてる気がする。システムテストに含まれるセキュリティとかパファーマンス観点のテストがアジャイルだと軽視されているように見える(暗黙的にやることになってる?) おそらくアジャイルでも随時そういったセキュリティとかのテストもやらなきゃいけない。つらそう。

アジャイルのテストはもう少し文献調査の必要がありますね。

あと用語の定義ってめちゃめちゃ大事だということを感じた。テスト周りが整理されてなさすぎる。