見出し画像

Practices of Software Engineering

本ドキュメントの利用は、https://github.com/kae-made/kae-made/blob/main/contents-license.md に記載のライセンスに従ってご利用ください。

はじめに

University of Nevada の Computer Science & Engineering のページによれば、

"Bjarne Stroustrup, the creator of the C++ programming language, once said that "our civilization runs on software." This statement is impressively backed by reality, in which software controls a huge variety of devices, from cell phones and music players, to smart appliances such as microwave ovens and laundry machines, to personal computers that many people use at work and large mainframe computers that operate in governmental organizations. In fact, it is hard to imagine an area of human activity that does not rely at least partially on software, including professional work, home activities, and entertainment.
Using a basic definition, software means computer programs and their associated documentation. Computer programs, in turn, consist of algorithms (or procedures) applied to various types of data. Software engineering emerged in the late 1960s as a new engineering discipline concerned with all aspects pertaining to software production. It encompasses concepts, principles, theories, techniques and tools that can be used for developing high-quality professional software. First introduced at the 1968 NATO Software Engineering Conference in Garmisch, Germany, software engineering emphasizes a systematic, disciplined approach to software development and evolution and typically applies to the construction of large software systems (or products) in which teams of numerous software engineers are involved.

とあり、ボールドで示した部分で、”Software Engineering” が定義されています。Software Engineering という言葉が、初めて言及されたのは、1968年、今から54年前のことのようです。

また、Wikipedia によれば、

”ソフトウェア工学はソフトウェアの開発・運用・保守に関して体系的・定量的にその応用を考察する分野である[1]。ソフトウェア工学は「工学」であり、ソフトウェアの信頼性・保守性・開発効率の向上などを目的とする[2]。
ソフトウェア工学には、設計法と生産法の2領域がある。設計法はソフトウェア構造(ソフトウェアアーキテクチャ)を扱う。ソフトウェア生産法はソフトウェアライフサイクルプロセスを扱う。これら二つの領域は利点と制約の面で相互関係がある。
ソフトウェア工学には、要求分析、ソフトウェア設計、プログラミング、ソフトウェアテスト、ソフトウェア保守といった作業に関する知識・ツール・手法が含まれる[3]。ソフトウェア工学に関連する学問分野として、コンピュータ科学、コンピュータ工学、経営管理論、数学、プロジェクトマネジメント (ソフトウェアプロジェクト管理) 、品質管理、人間工学、システム工学がある[4]。また、他分野とクロスオーバーしていたり、もしくはソフトウェア工学の1分野だったものが独立して別分野を形成したり(例:データベース設計)、別分野で培われた技術や概念がソフトウェア工学の対象となることもある(例:オブジェクト指向技術)。”

であると、より詳細に紹介されています。

Software Engineering は、

- 設計法
- 生産法

の二種類の領域からなっています。前者は、「Art of Conceptual Modeling」と「Essence of Architecture & Design」で解説している領域が相当するので、そちらを読み解いてもらうとして、本稿では、後者の「生産法」に焦点をあてて、話を進めることにします。
一方で、Wikipedia の「 ソフトウェア工学の曖昧性と論争」で解説されているように、ソフトウェア開発は、多分に人間の知的生産活動による部分が大きく、また、様々な知識領域、様々なスキルレベルを持った多数の人間が関与する活動であるため、Software Engineering が、科学的な合理性に基づいた純粋な“工学”であるかは微妙なところです。よって、本稿では、多人数が参加するソフトウェア開発を前提として、ソフトウェア開発プロセス、ソフトウェア開発マネジメントを行う上での実践的なプラクティスを紹介していきます。

“多人数が参加するソフトウェア開発を前提として”と、敢えて断りを入れているのは、数人で十分なソフトウェア開発の場合、ある程度のスキルを持ったそれぞれ仲の良い開発者が担当していれば、大したプロセスやマネジメントが無くても、それほど問題は生じないからです。本稿で紹介するプラクティスは、筆者がこれまで体験してきた経験上、特に重要と思われるものだけで、ちょっとググればヒットするであろう、数多あるソフトウェア開発に関するプラクティスのごく一部にすぎません。ネットや書籍で紹介されている様々なプラクティスに触れる際は、それが「50人以上が参画するようなソフトウェア開発プロジェクトで本当に機能するのか」という視点で検証してみるのも良いでしょう。

ソフトウェア開発プロセス

当たり前の話ですが、ビジネスを支援するソフトウェアを開発する活動も、ビジネス活動の一部です。ビジネス改革において、デジタルトランスフォーメーションが有効であるなら、ビジネス活動の一部であるソフトウェア開発においても、当然、デジタルトランスフォーメーションは有効であるはずです。この観点からすれば、ソフトウェア開発プロセスは、明確な手順と手順ごとの明確な設計方法があらかじめ定義されていなければなりません。これらを纏めてソフトウェア開発プロセスと呼びます。加えて、ソフトウェア開発プロセスに従った作業を支援するための、様々なツールやサービスで構成された開発環境も事前に選定しておく必要があります。全ての開発者は、ソフトウェア開発プロセスによって規定された開発環境を使って、決められた手順、設計方法に従って、ソフトウェアを開発していくことになります。
数十人が参画するソフトウェア開発では、開発者は7±2人程度を単位にチーム編成されるのが常です。チームは「概念モデリング教本」で解説したドメインを元に編成するとよいでしょう。各ドメインは、それぞれ全く異なる問題領域であり、必要とされる専門的な知識やスキルが異なるので、それぞれのドメインに適した作業手順、設計方法、開発ツールの選定を行います。ただし、チームメンバー間のコミュニケーションツール、プロジェクト計画・進捗管理、ソースコードの編集、ビルド、テスト、構成管理といったプログラムコード作成以降を支援する開発環境は、全てのチームが同一の環境を使わなければなりません。

画像1

開発環境を統一できるのは、上述の範囲に限られます。それ以上の範囲を統一しようとすると、それぞれのドメインを担当するチームは、帯に短し襷に長し的な環境を押し付けられて生産性と満足度を落とすか、密かに非推奨の(彼らにとっては最適な)開発環境が使われて、今度は統一しようと試みているチームメンバー側のマインドに悪影響を及ぼすなど、良いことは何もありません。もちろん、それぞれの開発チームのメンバーがそれなりのスキルと専門領域に関する最新の知見を持っている場合に限りますが、餅は餅屋、蛇の道は蛇です。統一したほうが購入や利用ライセンスの管理が楽などという理由で、ソフトウェア開発の邪魔は慎むべきでしょう。

ドメイン毎の開発を担当するチーム群の他に、

- 開発プロセスの定義と保守
- システム要件と全体アーキテクチャの管理
- 品質管理
- ソフトウェア開発の進捗や予算管理

等の開発活動を支援するチームも必要です。

ソフトウェア開発プロセスの定義

ソフトウェア開発は、ビジネス戦略に基づいた様々な要件と、利用可能なIT技術を入力として、ソフトウェア開発技法を駆使して、実際の HW 上で実行可能なモジュールを出力する一連の作業の流れです。入力から出力までの流れは、様々な作業工程から構成されており、この様なプロセスを可視化するには、データフローモデルが適しています。

画像2

図中の円をバブルと呼びます。それぞれのバブルは、そのバブルに流れ込む情報が利用可能になった時点で、あらかじめ決められた作業法に従って情報を加工し、加工した結果を、バブルから出力として生成します。後段のバブルは、自身に流れ込む情報が利用可能になった時点で作業を開始し、…、といった形で定義されていきます。これは、「概念モデリング教本」の「概念振舞モデル」の章で解説したデータフローモデルと同一です。バブルが実行される順番、つまり、ソフトウェア開発プロセスを構成する各ステップの作業工程の実行順序は、成果物の流れによって規定されることになります。成果物の依存関係が無いバブルは、同時並行的に実施可能です。バブルの実行主体として、各チームが割り当てられ、それぞれの作業を遂行します。

作業の自動化

定型作業は可能な限り自動化し、開発者が設計やコーディングに専念できる時間を増やしましょう。ソフトウェア開発プロセスの定義と、それに従った作業手順を開発者に強要するためのマニュアルが作成されることは、ありがちなことです。まじめな人ほど、詳細なマニュアルを作りがちですが、ほどほどの内容にとどめましょう。マニュアルは作成にかかるコストだけでなく、マニュアルに従うべき全開発者への周知徹底と開発期間全般にわたる監視活動が発生します。

マニュアルにかかるコスト=マニュアル作成コスト+開発者数×(周知徹底+監視)

加えて、マニュアル作成者が開発対象のビジネスから開発に必要な技術的な深く幅広い知見を網羅的に持っている社内の第一人者でない限り、プロフェッショナルな技術屋さん達は素直に従ってくれない可能性大です。それぞれのチームの開発対象の特性(開発に携わる技術屋さん達の特性ではないことに注意)に応じた定型作業の自動化や間接業務にかかる時間を短縮するような開発支援環境を導入し、その中にマニュアル化対象の作業手順や設計方法を埋め込み、開発者が日々の開発活動業務の中で自然に決め事に従うような運用を行います。

開発支援環境は、当然、最近のIT技術を活用して構築する(こちらもIT技術を活用したデジタルトランスフォーメーション)ので、開発支援環境構築もまた、ビジネス戦略に則ったITシステム開発です。論理的帰結として、開発支援環境に対する概念モデリングを行い、「概念モデリング教本」で解説した設計・実装方法での開発が行えます。
開発作業工程の自動化では、[DSL(Domain Specific Language)を使って、特定の問題領域の作業量を低減できます。

概念情報モデルで定義された概念クラスと関係を元に、概念インスタンス群と概念インスタンス間のリンクを定義するエディタを、モデル化対象の問題領域に適した表現形式で開発してやれば、それがDSLになります。表現形式は、対象ドメインの特性に応じて、スクリプト言語に近いテキスト形式の場合もあれば、GUI や特殊な Human Interface を持ったアプリケーション形式の場合もあります。概念クラスと関係を元に、開発作業工程の成果物を自動生成するルールを作成してやれば、エディタを用いて定義された情報から時間をかけずに必要な成果物が生成可能です。
テキスト形式は、記述しようとしている情報量が大規模な場合に便利です。GUIを使った図形式は、比較的小規模な情報か、大量の情報の中からフィルターをかけて絞ったものを対象にする場合に便利です。

画像6

参考情報ですが、Visual Studio は、Modeling SDK for Visual Studio を組み込むと、Graphical な UI を持つ DSL 環境の構築が可能です。この環境は元々は、2000年代後半に、Software Factory が流行った時に、それに合わせてリリースされた機能です。

もちろん、システム開発におけるありとあらゆる作業の全自動化を目指すわけではなく、あくまでも、適した作業工程だけを自動化することが前提です。
RPA(Robotic Process Automation)をはじめとする様々なローコード、ノーコード環境が実用化されている現代においては、流石に、もういないかもしれませんが、プログラムコードは手書きすべきだという信念を持っている様なプログラマーは、この手の自動化環境には否定的な意見を持つかもしれません。しょせん、プログラムコードは、コンパイラとリンカーという自動化ツールで実行可能な形式に変換されるものです。見方を変えれば、この自動化工程なしには HW 上で実際に動くソフトウェアは得られないので、プログラミングの自動化を禁忌する技術屋さんも使わざるを得ない自動化ツールということになります。開発者全員に自動化ツールを使ってもらうための解決策は、コンパイラやリンカーの様に、ソフトウェア開発プロセス上使わざるを得ない形で、開発支援環境に組み込むことです。
他にも、実装工程において、なんらかのフレームワークを利用する場合の、フレームワークを使うための定型コード作成や、決められた手順遂行も、自動化対象の有力な候補です。

フレームワークライブラリが想定する実装方針を自動化するサンプルとして、https://github.com/kae-made/dtdl-iot-app-generator を公開しているので参照してみてください。

作業の自動化に当たっての注意点はもう一つあります。それは、人が手作業で行っている一連の作業プロセスをそのまま自動化してはいけない、ということです。自動化した作業工程がよほど、定型的で、かつ、煩雑で時間がかかるものでない限り、そのような自動化は、単にコンピュータシステムへのデータ入力の手間を増やすだけに終わってしまいます。自動化に当たっては、作業そのものに着目するのではなく、作業開始のきっかけとなる入力情報と作業完了時点で生成される出力情報に着目し、どの様なルール群を適用すれば入力情報を出力情報に変換できるかを、データフローモデルを作成することによって明らかにします。この検討過程で、各バブルにおいて、暗黙的に依存している情報が新たに見つかるかもしれません。各バブルに対し、明らかになったルール群の中で、人の判断が必要なものと、不必要なものに分類します。その分類を元に、一つの作業工程を細分化し、全体のデータフローモデルを見直します。この過程では人が手作業で行うが故に必要なバブルが出てきます。例えば、人は間違いを犯すものだという前提に基づいたデータチェックなどです。この様な作業工程バブルは、自動化後は不必要なので、データフローモデルから消去していきます。そうやって出来上がったデータフローモデルを構成するバブル群の中で、人の判断が不必要なバブルだけが、自動化対象になります。最後に、自動化前と自動化後で、どの程度生産性が向上するか検証し、自動化後の方が自動化前よりも生産性が高ければ、自動化環境の構築を始めます。

開発プロセスを構成する様々な作業工程の中には、暗黙知による深い洞察を伴う閃きを必要とする知的活動が主となるものがあります。この様な作業工程の自動化には困難を伴います。そんな時は、ホワイトボードを使って、頭の中に浮かんでいる様々なイメージを、絵にしてみるとよいでしょう。絵はなるべく具体的に書いていきます。概念情報モデル作成のテクニックを使ってイメージを整理しながら、ホワイトボードを囲んで、メンバー達とディスカッションをしているうちに、適切な表現法(Presentation)と内容(Content)が明らかになっていきます。
適度な余白があり、簡単に何度も修正ができるホワイトボードは、不定形なものを定式化していくときに有効なツールの一つと言えるでしょう。

成果物のデジタル化

ITシステム構築の過程では、ソースコードも含め、仕様書や計画書、障害管理表、変更要求、労務情報、…、などなど、様々なドキュメントが作成されます。
これらのドキュメントは、当然のことながら作成の過程で電子化されて、ITシステム上のストレージに保管され、適切なアクセス権の元に、開発チーム内、あるいは、関連する外部組織と共有されます。この際、単にドキュメントを PDF や Word、Power Point、Excel 等のファイルフォーマットで作成するだけでは、デジタルトランスフォーメーションは実現できません。旧来のドキュメントは、人が見ることを前提としてフォーマットが決められて書かれています。このフォーマットはIT技術を活用してプログラムで活用する際に便利なフォーマットとは一致しないのが普通です。

そもそもドキュメントは、そのドキュメントの目的に応じた中身(Content)と、人が読むときに見やすく誤解を与えないような見栄え(Presentation)の掛け算からなっています。Web ページが、中身を記述した HTML ファイルと、表示の際のウィンドウのサイズごとに用意されたCSS ファイル(Style Sheet)の組合せで表示されるのと、基本原理は同じです。
ドキュメントをデジタル化する際は、Content の構造を概念情報モデルで定義して、XML や RDF、JSON 等で、概念情報モデルに従って記述された概念クラスのインスタンスとインスタンス間のリンクに関する情報を保持するようにし、人が利用する場合には、PDF、Word、PowerPoint、Excel 等、利用目的に応じた Presentation を適用して、ファイル化して利用するようにするとよいでしょう。この様な形式でドキュメントがデジタル化されていれば、作業工程の自動化においても非常に便利です。

画像7

デジタル化することにより、人が手作業で行っていた作業工程を自動化できるようになるだけでなく、上級者の知識とスキルを定式化してプログラム化することにより、上級者の深い見識や技をスケールすることができます。達人級であろうと、人である限り、限られた時間で一人が生み出す成果物の規模は、巨大なITシステムの全貌に比べれば、たかが知れていて、分身の術でも使わない限り、同一時間における生産量を増やすことは不可能です。クラウドの利用により、人的コストに比べて安い料金で、必要なだけのコンピューティングリソースが使える昨今、上級者のナレッジを自動化によってスケールするのは、良いアイデアだと思われます。

将来的には、構築しようとしているITシステムの要件をイメージ化したスケッチや動画などを入力すると、概念情報モデルの概念インスタンスと概念インスタンス間のリンクを自動生成してくれる AI が現れるかもしれないですね。
自動化=ツールの導入です。ツールによるプロセス改善では、伝統的に、「ツールが全てではない」という意見を言う人に良くお目にかかります。その意見が、「だから、ツールを上手く活用するための施策をもっと考えよう」という話題につながればいいのですが、往々にして、「だからツールの導入には意味がないからやめましょう」という議論につながってしまうのが残念です。デジタルトランスフォーメーションを標榜する以上、何らかのツールを駆使してプロセスを見直すのは当たり前です。もちろん、見かけ上華やかな図は作れるけれど、単に開発者の仕事を増やすだけの、本末転倒なツールもあるので、なんでもいいからツールを導入しようというわけではありません。人的リソースには限りがあり、人的コストに比べれば格段に安く使える潤沢なコンピューティングリソースが利用可能になっている現在の状況を鑑みれば、定型化できる作業は極力ツールによる自動化を推進したほうが良いでしょう。ただし、専門性の高いツールは、それを使いこなすための専門的な知識とスキルが必要なのが一般的です。この様なツールの導入に当たっては、「ツールが全てではない」という議論に間違いはありません。必要な素養を獲得するトレーニングの提供や、それに取り組むマインドセットを獲得する施策が必要になります。前述のツール導入に否定的な意見は、本末転倒なツールの導入にうんざりしたり、高度なツールが使いこなせなかったような経験から生まれているようです。少なくとも、「使えるけれど、あえてツールを使わない」、と、「使いこなせないので、ツールを使えない」は、手作業中心に見える見た目は同じでも、その組織から出力されてくる、成果物の質と量は全く異なるレベルになるでしょう。
後工程で有効活用可能な形式で、成果物を構築するという観点に立って、作業工程の自動化を試みていると、形式だけでなく、記述内容をどの程度詳細に記述すればよいか、に関する適切な粒度が判ってきます。実務で概念モデリングを行う際、必ず「どこまで詳細にモデルを記述すればよいか」という疑問が生じますが、後工程での活用に必要な粒度という観点は、この疑問を解決する良い指標になります。
Essence of Architecture & Design」で、データフローモデルを使って設計したロジックをプログラムコードに変換する際、データの後段から前段に向かってロジックを組み立てていくと、すっきりしたコードが出来上がると解説しましたが、作業工程を考えるとき、往々にして、手元にある入力として使えそうな情報や、自分ができること(やりたいこと)をベースに考えがちですが、期待される出力(成果物)を起点にして、そのためにはどんな情報が必要か、どんな手段が適用可能かを逆算していくと、作業のためにどんな情報が必要か、複数の手段の候補からの“やるべきこと”のて季節な選択ができるように思えます。

ソフトウェア開発マネジメント

形のない(と思われている?)ソフトウェアだからといって、それを開発する組織のマネジメントに必要な技法は、ビジネス全般における様々な業務のマネジメントと変わりはありません。非定型なアイデアを定型化する頭脳労働が主であるので、工場における、個々の工程にかかる時間が明確に予測出来て原材料から製品までの一連の流れが管理可能な生産管理とは、明確に異なるのは確か(生産管理のマネジメント技法もいくつかの場面では利用可能と思われる)ですが、企画やセールス活動に対するマネジメントと基本原理は同じと思われます。
違いは、初期入力から成果物までにかかる作業工程が多岐にわたる事、出力以外の、入力情報と中間成果物を形式化し明確化するのが難しい、あたりでしょうか。
Software Engineering という言葉が提唱されてから半世紀以上たった現在においても、未だに、ソフトウェア開発活動で作成すべき中間成果物やそれに伴う工程が標準化されていないのも事実であり、特殊であると思われている要因の一つです。

マネージャの仕事

マネージャの第一の仕事は、開発チームが円滑にソフトウェアを開発するための資金を調達することです。資金を調達できないマネージャは存在価値0です。資金は、開発者の給料、開発チームの士気向上、必要機材の調達、開発支援環境の導入・運用費等多岐にわたります。適切な資金を調達するためには、IT システム構築に関わる QCD が管理できなければなりません。求められる Quality と Delivery を元に、かかる Cost を見積もって適切な額の資金の調達と、開発組織がそれに向けた正常な開発活動が行えるよう支援を行います。ビジネス戦略を達成するための IT システム導入は、その IT システムを導入する組織の経営層の判断の元に行われるので、マネージャは経営層との直接的なコミュニケーションが可能でなければなりません。資金の予算化と費消だけでなく、必要とするスキルを持つ開発者群によるチーム編成、開発の進捗に遅れが出た場合の、ステークホルダー達との折衝や計画変更も役割のうちです。

見積

ITシステム開発のQCDの、Qualityは、ITシステムが提供する機能やビジネスのカバー範囲、想定されるユーザーの種類と規模、応答性能や稼働率といった非機能要件からなります。これらはリスト化されて管理され、ソフトウェア開発プロセスで定義されたデータフローモデルを元に、最初の入力から、途中の中間成果物群を経て最終成果物である、実行可能なソフトウェアを構成するモジュール群までリンクを張ることにより、開発活動において発生しうる全作業をリストアップで切るとともに、各作業工程の順序は、成果物の依存関係で特定できます。後は、それぞれの作業工程がどれぐらいかかるかを見積もれば、プロジェクトのスケジュールに関するガントチャートが出来上がり、それぞれの作業工程が完了する時期が予測できます。見積もりの結果、求められているDeliveryに間に合わないことが判明したら、各工程の作業効率を上げる何らかの施策を編み出す、あるいは、チーム編成や担当を見直すか、発注者との駆け引きにより、部分的に機能を小出しにする段階的なリリースにするなどの施策を打って、予定スケジュール上のつじつま合わせを行います。

各作業工程にかかる見積では、開発担当者とマネージャとの間での駆け引きが往々にして発生しがちです。開発者はこれまでの経験から、ちょっと多めの見積りを提示するものなので、大抵求められている全体スケジュールには合致しません。結果として、ちょっと短縮された日数が提示されて、めでたく開発当初の全体スケジュールがコミットされるのですが、開発者の直感は案外当たるもので、結果的には開発者が当初見積もった期間はかかってしまうものです。これは開発者が怠けたからとか、能力が足りなかったからという理由ではほぼありません。新しくプログラムを作るということは当然未経験の部分もあるわけで、その部分の調査や不具合対応がどうしても生じてしまうからです。神ならぬ人の身が未来を正確に予測することはそもそも不可能です。

データフローモデルを元にしてガントチャートを作成し、各工程にかかる期間を見積もった場合、各工程の実行順序は、データフローモデルで定義された成果物の依存関係で決まります。次に、それぞれのバブルに対して、開発担当者を割り振っていきます。データフローモデルの各バブルは、入出力で依存関係が無い場合は同時並行的に実行が可能なので、割り振られた開発担当者が別々であれば、該当する作業工程群を同時並行的に行できます。各工程にかかる期間、中間成果物の依存関係、担当者の割当て方によって、その作業工程が開始可能な日時が決まります。この日時を“最速開始日時”と呼びます。逆に、後工程との関係から、その作業工程を開始しなければ間に合わなくなる日時も決まります。これを“最延開始日”と呼びます。それぞれの作業工程について、この二つの日時を割り出していくと、最速開始日と最延開始日が同じ日時の一連の作業の流れが出てきます。この一連の作業工程の流れを、クリティカルパスと呼びます。

画像3

このクリティカルパス上の作業工程のどれか一つでも期待以上の期間以上かかってしまうと、スケジュール全体の遅れが生じるわけです。逆に見積もった期間より短い工数で作業が終われば、別の一連の作業工程の流れにクリティカルパスが生じます。開発スケジュールの管理においては、各時点でのクリティカルパスを把握して、クリティカルパス上の作業工程群がオンスケジュールであるように手を打っていくことが肝要です。

そんな開発の進め方の代表格として、Scrum を紹介しておきます。

Scrum では、バックログと呼ばれる作業リストを作って、チームの進捗を管理します。
バックログの作業名は、データフローモデルによる作業工程群のバブルの名前より、各バブルの成果物を使った方が適しているように、筆者には思えます。
Scrum の場合は、ITシステムを細分化して、一つの期間(Scrum では“スプリント”と呼ぶ)で、実際に動くソフトウェアをリリースする事を目標とします。大規模なITシステムの開発において、全体のアーキテクチャが定まっていない時点から、実際に動くソフトウェアをリリースするのは困難であるのと、概念モデリングにおいては(利用する開発環境によっては、概念モデルを Simulator 上で実際に動かすことも可能ですが)、なかなかそうもいかないので、適宜、読み替えて、使えるプラクティスは取り入れる、でよいでしょう。

さて、作業工程の見積について、もっと掘り下げて考えてみます。作業にかかる日数を割り出すには、その作業工程で作成する成果物の規模をある程度正確に予測できなければなりません。ソフトウェア開発で昔から一般的に使われてきたのは、機能数を数え上げる FP(Function Point)法や、ソースコードのライン数あたりでしょうか。

現代の複雑化したITシステムで FP 法を使うのはなかなかに難しいのではないか、というのが筆者の素直な感想です。FP 法で洗い出す項目は、アプリケーションドメインの概念モデル化や、サービスドメイン群やインフラストラクチャドメインのモデル化によって明らかになる項目に思えます。モデル群と実装への変換ルールが出来たら後は機械的な作業でのコードへの置き換えであり、工夫すれば自動化することも可能なので、その部分を見積もれてもあまりありがたいとは言えません。むしろ、モデリングにはそれ相応の期間が必要なので、そちらを見積もる方法が欲しいところです。残念ながら、筆者は現時点でその答えを持っていません。筆者が推奨する開発手順では、アプリケーションの中身に依存せずに、“概念モデルの概念情報モデル”と非機能要件を使って、実装ルールの設計は可能なので、そのプロセスを Scrum でスプリントを回して構築しつつ、アプリケーションやサービスドメインのモデル化を一定間隔ごとにチェックポイントを設けて進捗を確認し柄、並行して作業を進めるのが良いでしょう。

ジャストアイデアですが、概念モデリングの作業見積は、機能要件のドキュメントから概念クラスや特徴値、関係の候補になりそうなキーワードをざっと拾い出して、その数に経験から得られた係数をかけると、近い数字が出てくるのではないかと、思っています。いずれにしろ、見積はしょせん見積であって、その見積がどのくらいの確からしさで実現できるのかという統計情報のはずなので、本来なら、その値の正確さを表す確率の値が伴っていないと意味がないでしょう。これは、ビジネスプランの売上目標数値も同じではないかと思っています。

ソースコードのライン数は、見積として使わないことをお勧めします。

外から見て全く同じ機能を提供するモジュールを開発する場合、スキルの高いプログラマーが書くコードは、スキルの低いプログラマーの書くコードより、コンパクトなコードを書くものです。その差は、数倍から数百倍以上にもなります。コンパクトなコードに仕上げるためには、適切な設計作業や実装の見直しが行われるので、場合によってはスキルの低いプログラマーの作業と同じ程度の時間がかかります。仮に、各プログラマーの能力を、一か月あたりに書いたコードのライン数で比較すると、(あら不思議)スキルの高いプログラマーの方が、生産性が低いという結果が出てしまいます。加えて、出来上がったコードが実行された時に発見される障害やバグは、スキルが高いプログラマーが書いたコードの方が当然少ないにも関わらず、母数の問題で、これまたスキルの低いプログラマーの書いたコードの方が高品質という結果になってしまいます。
また、気の利いたプログラマーならば、あるお題のコードを書いているときに、本筋のコードを書きながら、適度に汎用的に使える部分を抜き出してライブラリ化するものです。ライブラリを作成する分だけその時は余計に工数がかかりますが、作成したライブラリは後日、似たようなお題のコードを書くときに再利用されるので、ライブラリ作成は投資であり、
その先行投資は後で回収されるわけです。開発者の中には、コード開発を支援するユーティリティツールまでも、作ってしまう猛者もいることでしょう。

若干話がそれてしまいましたが、結論としては、見積でコードのライン数を使うのは意味がないということです。

1975年に刊行された、フレデリック P. ブルックス Jr. の「人月の神話」には、開発可能なコード量=一人月の開発可能コード量×人数は成り立たないことが書かれています。内容的には全くその通りだと思っていますが、元々、コード量と機能数は比例しないのと、同一機能数をコード化した場合のコード量とプログラマーのスキルは反比例(二乗・三乗、あるいは指数関数的かも)するものなので、もっと違う表現が適しているのかなと、思ったりもしています。筆者は昔々、この本を購入して読んだ記憶がありますが、生憎今手元になく、読み返すことができません。もしかすると、色々と誤解して記憶している恐れもあります。本稿を執筆している過程で見つけた、こちらの https://www.gixo.jp/blog/4978/ の記事、非常に参考になりました。ありがとうございます。
他にも、エドワード・ヨードンの「デスマーチ」、トム・デマルコの「ゆとりの法則」はプロジェクトマネジメントにおいて、様々な示唆を与えてくれる名著です。
本文の中で、「プログラマーのスキルによってコード量は数百倍違う」と書きました。読者の中には、ほんと?と思っている人が多いのではないでしょうか。しかし、不幸にも、著者が目の当たりにした事実に基づいています。当時、組込み制御ソフトウェア開発のプロセス改善を担当していた筆者は、実際に製品に搭載されているコード(数百万行規模)を、ソフトウェアメトリクス計測ツールも使いながら、調査を行っていました。さるプログラミング言語の勉強会を自主開催するような意識高い系のチームが書いたコードでしたが、オブジェクト指向設計の基本を習得しているプログラマーであれば同じ機能を、二百分の一で書ける内容でした。ご丁寧に全てのソースコードには、コードレビューをして承認された記録が残っていましたとさ。
同時に、MaCabeの複雑度をはじめとする様々なメトリクスをモジュール毎に計測してみましたが、定性的な分析で上がった様々な開発活動中の問題と明確に関係すると思われるメトリクスは、ほぼ皆無でした。

見積は、これから始めようとしている作業にかかるコストを、過去の経験を元に行う、行為です。従って、過去の経験がなければ、そもそもの話、正しい見積は行えません。必要な要件に合致したソフトウェアが既にあるなら、それは購入すればよいだけの話なので、各組織におけるソフトウェア開発は、常に未知の新しいものが開発対象になります。結果的として、見積基盤として役立つ、過去の知見はないと思ったほうが良いでしょう。

障害管理

構築されたソフトウェアを規定の実行プラットフォーム上で稼働している時、想定とは異なる動作を行ったり、規定された応答性能が達成されないなど、システム要件が満たされない事象が発生することを“障害”が発生するといいます。障害が発生した場合は、ソフトウェア開発部門が調査を行って原因を特定し、解決手段を検討して、適切な方法で原因となっているモジュールを修正しなければなりません。障害発生を検知したら、その症状を具体的かつ詳細に記録し、関連する要件が記載されたドキュメントと紐づけて保存します。記録された障害には原因を特定する担当者が割り振られ、障害発生条件の特定や、障害発生の現象からの設計資料を基にした論理的な推測等を元に、障害を引き起こしていると思われるモジュールを特定します。原因特定の過程では、疑わしいモジュールの開発を担当したチームも参加して、担当者と協力して原因の特定を進めます。障害の発生を引き起こしているモジュールが特定されたら、そのモジュールの開発担当チームが障害を引き起こしている原因を明確にし、解決のための修正案を検討します。一つの障害として認識されている現象を引き起こしているのが、複数のモジュールである場合もあります。その場合は、該当するモジュールを担当している複数のチームが解決策の検討と修正に当たることになります。問題解決のためのソースコード修正は、別の新たな障害を引き起こす可能性もあるので、自動テスト環境を使った動作テスト(“レグレッションテスト”といいます)を行い、悪影響が無いことを確認した後に、構成管理システムに修正済みのコードを反映します。障害対応が終わったら、障害管理システムに解決した旨の記録を行います。原因モジュールの特定、原因箇所の特定が成された時点においても、障害管理システムへの記録が必要です。

また、障害は一つづつ時系列的に発生するわけではなく、同時並行的に行われているテスト活動中に複数の障害が並行して発生し、一つの障害への対応中にも複数の未解決の障害がバックログ的に累積されていきます。ある障害対応の活動中に発見された問題個所が、別の障害として管理されている現象を引き起こしている場合もあるので、原因となった問題が別の障害を引き起こしていないかを、論理的に検証し、該当するものがあれば、関係者の合意の元に、該当する障害が解決した旨、障害管理システムに記録していきます。

画像4

障害原因を調査する担当者の数は有限なので、担当者の数以上の複数の障害が発生した時には、全ての障害に対して担当者を割り振ることはできません。また、疑わしいモジュールが特定された時点で、そのモジュールの開発担当チームが、別の障害対応を行っている場合には、該当する障害は、その開発担当チームの障害対応リストのバックログとして保持されることになります。バックログとして保持された障害は、プライオリティがつけられて、どれから手を付けていくかが決まります。プライオリティは、

- その障害が解決された後に得られる利益
- その障害を解決しなかった時に被る不利益

を元に決めるとよいでしょう。

障害発生時の原因の一次調査を、モジュール開発を担当しているチームのミッションとするのは避けた方がいいでしょう。開発チームは多忙なものです。下手をすると開発チーム間での障害原因の押し付け合いが発生し、開発組織全体の士気を下げかねません。また、ソフトウェア開発においては、障害発生は当たり前のことなので、モジュールごとの障害発生件数や障害発生率をチームの能力の査定に使うのも上策とは言えません。新しいチャレンジが多いモジュールや複雑なロジックを含むモジュールは障害が多発しがちであるなど、障害発生率は、それぞれの担当モジュールごとの事情に左右されるので、単純に並べて比較することに意味はありません。開発者の士気をそぐだけです。

著者は、実際の開発活動で使われていた障害管理データベースに蓄積された情報の解析を試みようとした経験があります。そのデータベースは、有名なリレーショナルデータベースを使って構築されていました。時代を考えると、そのこと自体は非常に先進的だったのではないかと思われます。しかし、情報分析のために、障害管理システムの担当者に、データベースのスキーマを見せてほしいとお願いしたところ、返ってきた答えは「スキーマって何ですか?」。著者もデータベースの専門家ではなかったので、聞き方を変えてみたのですが、そのデータベースは一枚のテーブルで作られている、つまり、データの正規化は一切なされておらず、そのデータベースを操作するロジックで吸収するという代物でした。結果として、図で示した障害管理で扱う情報の構造は、カラムの中に自然言語で書かれた内容に埋没するようになっていました。その事実が判明した時点で系統だった分析は工数の余裕もなく、あきらめざるを得ませんでした。AI技術が発達した現代なら、それを駆使すればある程度の分析はできたかもしれないですが、図で紹介したような構造を元にしたスキーマで作られていれば、AIを使うことなく、著者が知りたい情報は得ることができたはずです。この経験から、世の中で実際に稼働しているシステムのうち、正規化されたデータスキーマで作られたデータベースを持つシステムの割合はどれぐらいなのかについて、著者はずっと興味津々です。

レポート

ソフトウェア開発者にとっての間接業務の最たるものが、日報や進捗レポートではないでしょうか。他にも、テスト中に発生した障害報告、開発過程で生じた開発者個人では解決できない問題の報告、定期的に開催されるレビュー用のレポート作成、等々もあるでしょう。

デジタルトランスフォーメーションの観点からすれば、これらの間接業務は、要件定義ドキュメントや障害管理と連携した構成管理システムを上手く使いこなすことで、そのほとんどが自動化できると考えています。構成管理システムには、ソフトウェア開発者が構築した、概念モデルや、設計ルール、実装コードが履歴とともに蓄積されているので、その蓄積情報から、日々行った作業の大枠は自動的に吸い上げてレポート化が可能です。ソースコード以外の様々なドキュメントも、開発支援環境の一部のストレージに保持されているはずなので、そのドキュメントの URLを構成管理側でリンクとして持っていれば、十分トレースできます。開発過程で発見された問題も、何に対する問題なのかを、構成管理システムで管理されている情報とリンクして報告すれば、解決する側も情報収集の手間もかからず便利です。これらの情報をリアルタイムで収集し、進捗メトリクスごとに整理された形で表示されるダッシュボードを構築し、ITシステム開発に関わる全てのステークホルダーが参照可能にしておけば、ITシステム開発状況の健全性が一目でわかります。開発中に見つかった問題や、実装済みの機能要件の増加率を元にした進捗遅れ等、開発スケジュールに影響を及ぼしそうな問題の発生もダッシュボードで表示できるようにしておけば、開発者の貴重な時間を割いて行われる、レポート作成やマネージャによる現状の聞き取り等も最小限に抑えられるでしょう。

文中で、“問題”という言葉を使っていますが、正確には、“問題”とは、理想と現実のギャップのことを言います。そのギャップを埋めるために行わなければならいことを“課題”といいます。つまり、理想的な状態が不明確で、現状が正確に把握されていない場合は、正確な意味での“問題”は存在しないということです。

アーキテクチャの順守

Essence of Architecture & Design」で解説したアーキテクチャは、ITシステムの骨格であり、モジュールの開発においては、アーキテクチャの定義に従って開発を進めることがとても重要です。それぞれの開発者が自分の好みで開発を行うと、ITシステムは継ぎ接ぎだらけのおんぼろ煙突化になってしまう恐れがあります。
本稿で紹介しているソフトウェア開発プロセスに関するトピックスもアーキテクチャ駆動での開発を前提としています。
IoTソリューションをはじめとする、大規模なITシステムの開発と運用では、よく、「小さく始めて大きく育てる」という言葉が使われますが、これは、全体のアーキテクチャを定義した後に、部分ごとに開発し、少数のユーザーから初めて、徐々に増やしていくことを意味しています。現場の担当者が、場当たり的に、出来るところから作っていくことを意味するのではありません。開発は、アーキテクチャでの決定事項に従って進められます。よって、開発チームは、利用する実装技術や開発支援ツールを、アーキテクチャで決められた選定基準に従って、アーキテクチャを管理するチームの承認とともに選定し、開発を進めなければなりません。

ソフトウェア技術者のスキルアップという観点では、複数のプログラミング言語や、オープンソースを含めた様々なベンダーが提供しているツールやサービスを実際に使ってみることは非常に重要であり、推奨されることではあります。しかしそれは、あくまでもソフトウェア技術者としてのハイレベルなスペシャリティを獲得するための学習の場での話です。仕事としてソフトウェアを開発する場合は、個人の好みによらずに組織の方針に従いましょう。逆に、ソフトウェア技術者が所属する組織は、様々な実装技術を体験できる機会を用意すると、ソフトウェア技術者のモチベーションが向上し、ソフトウェア開発に必要なセンスも磨かれると思われます。

ソフトウェア技術者のスキルアップ

1989年にベルリンの壁が崩壊し、東西冷戦が終了してから30年余り、昨今の米中対立やロシアのウクライナ侵攻による若干の陰りはあるものの、グローバリゼーションが進み、国内向けに限定されたサービスは除き、製品開発にしろ、ITサービスにしろ、全世界の企業がそれぞれの産業分野で競争を行うようになりました。グローバルマーケット向けの製品開発も含め、ITシステムは、ワールドワイドでのビジネスを支えるものであり、それを開発する技術者に求められるレベルは、ある意味、オリンピックでメダルを競い合うスポーツ選手と同等と言えるのではないでしょうか。
そこで、読者に質問です。

「メダルをとれるスポーツ選手を育成する定型化された育成方法は存在するか?」

現実を見れば、そんな都合のいい“銀の弾丸”は存在しないといっていいでしょう。たとえ、一部の読者から、「ある競技で多くのメダリストを輩出する国があるではないか」という声も聞こえてきそうですが、あの国は結局、若年層の使い捨てやドーピング疑惑等、果ては別の問題を引き起こして、国際大会への参加すらできなくなりました。ビジネスでは、従わなければならない倫理や法律をないがしろにした結果、市場からの退場を余儀なくされることと同義です。若干、話がそれてしまいました(苦笑)が、オリンピックのメダリスト並みのソフトウェア技術者が組織にいるに越したことはないでしょう(笑)。

ソフトウェア技術者の育成では、日本の伝統の茶道や武道で昔から伝えられている、“守破離”のステップに従うのが良いと、筆者は考えています。

- 守 - 最低限の基本的な知識を身につけ、無意識でも基本に従った開発ができるようになる
- 破 - 敢えて、基本的な決まり事を破って、応用力を高め、根本原理を悟る
- 離 - 様々な例外的な問題に遭遇しても根本原理に反せずに、自在に解決できる

筆者の経験を踏まえ、若干デフォルメをしていますが、元々の意味とそれほど乖離は大きくないでしょう。組織が提供できるのは、“守”のレベルに対する教育だけだということは、多くの読者の賛同を得られるのではないでしょうか。
そして、そのための下地となる、教育コンテンツを提供する側は、本当に必要な知識群を系統だって、開発者に提供しなければなりません。初期の段階で筋の悪いコンテンツで教育を行うと悪癖が身についてしまいます。一度身についてしまった悪癖を直すには、悪癖を身につけさせるのにかかった以上のコストがかかってしまいます。特に、特定の言語によるプログラミング作法のみの教育は最悪です。残念ながら著者は、教育の専門家ではないので、系統だったコンテンツを提供することはできませんが、「Art of Conceptual Modeling」と「Essence of Software Architecture & Design」に書いている内容は、これまでの経験から役に立つことが判っているので、教育コンテンツの中身として活用していただければ幸いです。
“概念モデリング”で言えば、“守”になったレベルの開発者は、要求仕様や普段の仕事の中で出会う様々なシーンで、ドメインや、概念クラス、関係の候補が、概念モデリングの形式的な知識に基づいて、自然に頭に浮かんでくるようになります。人間の脳みそは、何度も何度も同じ思考パターンを繰り返すと、AI のニューラルネットワークと同じように、シナプスの回路が出来上がり、自然にその回路が反応するわけです。筆者の経験よれば、必要な知識の提供と、その知識を使ってモデルが作成できるようになるためのトレーニングに必要なサンプルと手順は、定型化された教育コースとして提供可能です。ただし、お題を変えて何度も何度も繰り返して習得する過程は、各個人が自ら実践しなければなりません。
そして、そのための下地となる、教育コンテンツを提供する側は、本当に必要な知識群を系統だって、開発者に提供しなければなりません。初期の段階で筋の悪いコンテンツで教育を行うと悪癖が身についてしまいます。一度身についてしまった悪癖を直すには、悪癖を身につけさせるのにかかった以上のコストがかかってしまいます。特に、特定の言語によるプログラミング作法のみの教育は最悪です。残念ながら著者は、教育の専門家ではないので、系統だったコンテンツを提供することはできませんが、「Art of Conceptual Modeling」と「Essence of Software Architecture & Design」に書いている内容は、これまでの経験から役に立つことが判っているので、教育コンテンツの中身として活用していただければ幸いです。

Engineering の Practices を適用して、構築されるソフトウェアは工業製品ですが、それを生み出すソフトウェア技術者は生産ラインで製造されるような工業製品ではありません。手順書やマニュアルを揃えれば、一定品質以上のスキルを持つ技術屋さんが育つというような幻想は捨てた方が良いでしょう。

次に、“破”と“離”のレベルにするための方策はあるでしょうか。“破”はぎりぎりあるように思えますが、“離”は、個人の資質、才能、センス、嗜好に左右される不定形な世界に思えます。著者は、技術系エバンジェリストとして、非常に多くのソフトウェア技術者と出会ってきました。その過程で、幸いにも、達人級の“離”レベルの技術者と知り合いになることができました。その経験からの結論は、「達人は勝手に達人になる」です。“技術者の育成”となると、育成方法を考える側は、「どうやって育てるか」と考えがちですが、育成される側の各個人は自立的に育つものなので、育つためには何が必要か、という観点から方策を考えるのが良いのではないかと、筆者は考えています。

いつのころからか、「技術者もビジネスセンスを持つべきだ」という意見が言われるようになりました。ビジネスセンスはあればそれに越したことはありませんが、ソフトウェアの開発に必要な専門知識とは異なる問題領域の専門性が必要となるわけで、それほど簡単なことではないように思えます。筆者の素直な感想としては、「ビジネスマンもITの技術センスを持つべきなのではないか?」、なのですが、少なくとも、自分が作っているものを利用するユーザー要件を理解するセンスと、コスト意識は持っていたい方が良いでしょう。コスト意識には、単に自分の作業工数や使っている開発用の機器やソフトウェアにかかる費用だけでなく、作業工程の中で作っている成果物が、後工程でどれだけ活用されて、利益を生むか、または、コストダウンに寄与するかを考えて、仕事のやり方を見直すことも含まれます。

組織としてのスキルを上げるという観点においては、アンチパターンのカタログ化が効果的なのではないかと思っています。
失敗した時に、何故それが失敗したか、原因を探って、「こういう状況で、こんなことをすると、こんな不味いことが起こる」と一般化して、“アンチパターン”として定義し、組織内で共有します。アンチパターンには、失敗する確率と連動する指標が含まれているので、その観点を、ソフトウェア開発プロセス支援環境のレポーティング機能に組み込めば、マネージャは、労せずして、失敗の兆候を把握できます。
気が付けば、本稿の多くの部分を、アンチパターン的な説明が占めています。

コミュニケーション

筆者の経験によれば、良好なコミュニケーションができているチームほど、出来の良いソフトウェアを短期間で仕上げることができる傾向にあります。モデリング、設計、開発、コーディング、テスト、運用と、様々な作業工程での活動中には、大小にかかわらず様々な問いが生じます。仕様に関する素朴な疑問や、実装に関する利用時のテクニック、リリースに関する細かな取り決め、等々、問いが生じたら、間を置かずに解決できるのが理想です。同じ場面を見ても、感じるところは人によって違ったり、しょせん人は自分が知っている範囲でしか物事を考えられないので、「手っ取り早く知っていそうな人に聞くこと」が、問いを解決する有効な手段です。筆者が現役のソフトウェア開発者だった20年近く前とは異なり、今や、Slack や Teams を使って離れた場所にいる戦友たちともチャットやビデオ会議ができ、Live Share を使えば、VS Code で、同じエディタの画面を見ながら共同作業もできる時代になっています。

この様な便利な環境を使わない手はありません。積極的に活用して、生じた問いは On Timeで解決することにより、小さな誤解が後で大きな災いになって降りかかってくるようなことが無いようにしましょう。

コミュニケーションについては、いくつか注意が必要です。
まず、政治的な駆け引きを持ち込まないことです。政治的な駆け引きは、予算取りやシステムの発注者とのスケジュール調整では時に必要になるかもしれませんが、同志であるはずの開発組織内のメンバー間では必要ありません。宗教がかった思い込みによる押し付けも不必要です。合理的かつ論理的な思考の基でコミュニケーションを行いましょう。最後は自戒も込めてですが、相手に合わせたレベルの内容でコミュニケーションを行う事も心がけなければなりません。専門用語の乱発や、高みに到達した技術者でないと解らない機微に触れるトピック等々、これは一種のコミュニケーション拒否の態度ととられても仕方ありません。コミュニケーションは相手の技術スキルや立場に応じた内容にすることを心がけたいものです。

チーム内のコミュニケーションを常に良好に保つのは、チームリードの役割であり、チーム間のコミュニケーションを常に良好に保つのも、チームリードとマネージャの役割であり、開発組織全体のコミュニケーションが良好な状態を保つことに常に注意を払いましょう。

ソフトウェア開発が進んでいく様々な局面では、あるチームと別のチームの間で利益衝突が起こる場合もあります。そんな局面での恫喝的なコミュニケーションや、一方が過度の被害者意識をもって(装って?)、相手を攻撃するような態度はもってのほかです。人間は知性と感情からなる存在であり、感情のもつれや、特定個人の思い込みから起こる紛争を調停するのは、なかなかに困難ではありますが、開発に参加しているチームは、開発対象のITシステムのユーザーの為に仕事をしていることを再認識させて、その目的に対して、それぞれのチームが何をすべきかを考え、解決を図るのが良いと思われます。また、この様なケースでは、表面化している問題の裏に、その問題を発生させている隠れた思惑や過去の経緯があるものなので、根本原因を探って適切な処置を行わなければなりません。表層的な解決策だけでは、顔に笑顔を浮かべながら、右手で握手しつつ、左手で殴り合うような状態が続き、開発組織全体の士気を下げてしまいます。

ITシステム構築のためのソフトウェア開発においては、ソフトウェアを構成するコードを作成する開発者が主役です。しかし、主役が輝いて生き生きと活躍するためには、これまで述べてきた、ドキュメントのデジタル化、作業工程の自動化、構成管理、障害管理、レポーティング、コミュニケーション支援環境などなど、開発支援環境が非常に重要な役割を演じます。それらを構築し、日々滞りなく開発が進むよう運用を担当するチームは、経営層が描くビジネス戦略に合致する様に、開発チームが有するソフトウェアを開発する戦術を回すための、作戦(Operations)を担う、ある意味、主役以上に重要なチームであるといえるでしょう。

ソフトウェア開発プロセスの継続的な改善

Essence of Architecture & Design」の「リファクタリング」の章で、ソフトウェアの継続的な見直しを解説しました。ソフトウェア開発プロセスも、継続的に見直し改善していくことが求められます。大人数が参画するソフトウェア開発においては、“ソフトウェア開発プロセスを定義して終わり”、ではありません。3回程度のリリースサイクルを回さないと、まともに機能するソフトウェア開発プロセスの確立は困難です。まだまだ経験が浅い開発組織の場合は、常に、開発者が快適に作業を行っているか、見込み通りソフトウェア開発の進捗が進んでいるかをチェックしながら、不適切な部分は、都度々々修正を加えながら合理的なプロセスを確立して行きます。加えて、IT技術を活用した開発支援環境を活用するので、開発者にとって使い勝手の悪い機能の修正、自動化する範囲を漸近的に増やす、IT技術の進歩に合わせた環境の改変作業、等も継続的に行っていく必要があります。

プロセスを変える時の基本的な考え方は、

- ソフトウェア開発者の作業工数における、間接工数の比率を極力減らし、直接工数の比率を最大化する
- 機械ができることは機械に任せて、人しかできないことに多くの時間をかけられるようにする

です。間違っても、開発者の負担を増やしてマネージャの業務だけが楽になるような改悪をしてはなりません。

プロセスの見直しには、それ相応の投資が必要です。ソフトウェア技術者個人々々のモチベーションに依存した改善活動(それはそれでやるべきでしょう)ではなく、会社の方針としてプロセス改革を行う場合には、それにふさわしい専門家の協力を得て、合理的な改革を正しく進める必要があります。手を抜いたり、見かけだけの改善で済ましたりと、間違った改革もどきで進めてしまうと、当然見込まれる成果は上がらないにもかかわらず、現場の技術屋さんたちのプロセス改革とは無関係のたゆまぬ改善活動によるちょっとした成果がすり替えられて、経営層は最先端の開発プロセスを採用していると錯覚し、本来解決しなければならなかった放置された問題を解決するためのプロセス再改革を発起するのが難しいという、困難な状況に陥ってしまうかもしれません。

改善や改革では、大抵の場合、数値目標が掲げられます。数字による管理は一見すると非常に合理的に見えますが、使い方を間違えると組織に様々な弊害を引き起こします。現実は、様々なステークホルダーの思惑が絡む複雑な世界です。それを単純化してシンプルで、かつ、数個の数字で表現する訳で、削ぎ落されてしまう事項も多いはずです。“複雑な事情を分かったうえで、数値で管理できる”ことと、“複雑なのでとりあえず単純化した数字でしか管理できない”ことは、「Essence of Architecture & Design」で取り上げた、「特定のプログラミング言語で開発できる」のと「特定のプログラミング言語でしか開発できない」と同じような問題を含んでいるように思えます。
概念モデリング流の視点で考えると、数値は、“改善や改革を行うという問題領域を構成する概念クラス群の中のどれかの特徴値のうちのどれか”、ということになります。モデル化することにより、問題が整理され、作業工程や成果物、目指す状態の関係が明確になり、複数の数値項目の間の矛盾も解消されます。問題の構造を明らかにしたうえで、数値化できる項目を、統計学に基づいた確率を伴いながら、プロセスの成長の目安として利用するとよいでしょう。

マネジメント層が出してくる数字に魂がこもっているかいなかは、案外、現場の担当者たちには見透かされるものです。魂のこもっていないやっつけの数字は、数字達成の為だけに働いているとは思っていない技術屋さん達のやる気をそぎ、見かけの数字で評価されるだけのやっつけ仕事をする人たちを増やしてしまうこともあるので、注意が必要です。

数値による管理や評価については、昔から色々と思うところがあり、下手をすると私怨交じりの御託が並びそう(苦笑)なので、ネットで検索して見つけた良記事「測りすぎ:業績評価が組織をダメにする?|柏木亮二のDX Book Review | 野村総合研究所(NRI)」を紹介することにします。数値の管理だけでなく、何事も、正しくほどほどに適用すること、正解のない問題を扱っているにもかかわらず、正解があること前提の方策をとる事、このあたりが、肝要なのではないかと。

1990年代後半から2000年代初頭にかけて、筆者は、ソフトウェア開発プロセス改善に携わっていました。その中で活用していたのがCMM(Capability Maturity Model)です。CMMはプロセスの成熟度という観点からプロセスの良し悪しを判断する指標を与えてくれます。

画像5

当時、取り組んでいたCMMは、現在では、SW-CMMと呼ばれて、CMMI(Capability Maturity Model Integration)の一部になっているようです。ソフトウェア開発プロセス改善に当たっての留意すべき項目や、進捗に関する指標が欲しい場合には参考になる標準です。あらためて段階的にステップアップしていく CMM のモデルを眺めると、本稿で解説しきたプラクティス群は、Level 3 以上になるための実践プラクティスであり、実践するには、少なくとも、同程度の内容を同程度の QCD で開発できるような組織だけに有効なのかもしれません。

プロセスの改革に限らず、改善活動も含め、抜本的な改革には、相応の資金があるときにしか実行できません。資金がなくなった後にできる施策はコストダウンや事業規模の縮小ぐらいのものです。ジャック・ウェルチ流の“選択と集中”を持ち出したところで、これは、空腹のタコが自らの足を食って腹を満たすようなもので、賢明な読者諸兄には、そんな組織が最後はどうなるか、容易に想像がつくでしょう。

改善・改革は、ビジネスがうまくいって回っている時にこそ始めましょう。


改革を実践する

ソフトウェア開発プロセスを変えていくということは、影響の大小にかかわらず、組織の現状を変えていくということを意味します。数人規模で行っている開発であれば、それは、比較的容易な行為だと思われますが、数十人、数百人が参加するような大規模な開発の場合には、経営層の支援も必要とする、非常に困難な取り組みになることを覚悟しなければなりません。
最後に、この様な難しい取り組みに、果敢にチャレンジする奇特な方に向けたプラクティスを紹介して、本稿を閉じようと思います。

プロセス改革を実際に行うのは、改革を主導する側ではなく、現場の開発者達です。数十人、数百人となると、様々な人がいて、それぞれのモチベーションにおいて、日々の開発行為を行っているわけです。日々、様々な面倒事を解決していかなければならない、現場の開発者達は、目の前にある仕事を片付けたいのであって、改革を主導する側が提唱する小難しい理屈を知りたいわけではありません。多くの人が、素直に耳を傾けてくれないからと言って、自棄を起こしてはいけません。また、とかく、改革を推進する側は、様々な知識や情報に触れる機会が多いので、とかく、上から目線での活動になりがちです。現場を知らずに理念と知識だけが先走った改革が、現場の反感をかってしまうのは当たり前のことです。現場のことを一番知っているのは現場で汗水流して日々難問に立ち向かっている担当者たちです。現実はいかなるものかをご教授願って、一緒に問題を解決していこうという姿勢が大事でしょう。
改革する側が導入を試みようとしている施策が筋のいいものであれば、時間の経過とともに、徐々に賛同者は増えていくはずです。

1:2:4:2:1の法則というものがあります。新しいことをやろうとした場合、積極的に改革に協力してくれる人は、約一割、まぁ、やってもいいかなと、いう人は、約3割が大体の目安になります。

> この法則、過去誰かが正式に提唱しているのかと、今回改めて探したところ、1:2:4:2:1を扱っている投稿を見つけました。確か、正規分布から来ていたような覚えがあります。定かではありませんが、大抵の場合、感覚的にはそんな感じの分布になります。

活動を進める上で、対象になっている全体の人数に対する、協力者の割合を計算して、大体この割合になっていたら、普通に改革が進んでいると思ってよいでしょう。他の、4割は、どちらでもよい人達で、本当に、改革する側が進めている施策が、彼らの仕事を楽にするものであるなら、比較的抵抗せずに従ってくれるはずです。残りの2割は、「新しいことは、できれば、やりたくない」人達です。特段の理由があっての拒絶なら別ですが、新しい作業工程や開発支援環境を使わないと、業務が遂行できないような施策を打つとよいでしょう。
最後の1割は、「絶対にやりたくない」という人たちです。拒絶の理由が、

- その人が重要と考えている事が、改革側が推し進めようとしている施策でないがしろにされている、と感じている
- 過去に同様な取り組みにチャレンジして、失敗している

からだとすれば、むしろ、改革側に入ってもらい、施策をより実効的かつ、現実的なものにしてもらうことに協力してもらうとよいでしょう。特に、本稿で強調している自動化を主体としたプロセス改革では、自動化で消える手作業の部分に熱い情熱を感じている開発者からの反発には凄まじいものがあるので、注意が必要です。

当たり前の話ですが、組織全体のソフトウェア開発プロセス改革は、組織としての活動です。改革を行う組織の経営層が、強力にバックアップすることは前提です。開発組織の改革への抵抗が強い場合は、改革推進側の人達のメンタルケアも行ってもらいつつ、導入に対する強力な支援を得るようにしましょう。

改革を進める側が取り入れようとしている、施策、プラクティス、開発ツールなどが、本当に役立つものなのか、推進側での自問自答も当然必要です。もし、他にもっと良いものがあるなら、素直に取り入れていく度量も必要でしょう。
自社に閉じた知見に則ったものではなく、ソフトウェア開発を必要とする業界全体で、良いとされているものであれば、賛同者は、社内外で必ず増えていきます。
改革を推進する上で獲得した技術スキルや経験は、自分が所属する組織では必要とされなくても、他社で必要とされる確率は高くなっていきます。

確固たる信念を持つのはいいことですが、「こうあらねばならない」というような強迫観念を持つのはお勧めできることではありません。ゲームや実験をしているような感覚で、「ここが駄目なら、他の場所で頑張ろう」、ぐらいの気持ちで、取り組んでみるとよいでしょう。

最後に

以上、筆者の30年来の体験を通じて獲得してきた知識に基づいて、Software Engineering に関する様々なプラクティスを徒然なるままに書いてきました。本稿を読んで、いくつかのプラクティスに是非取り組んでみたい!と思ってくれた読者が一人でもいればハッピーです。以上、著者がこれまで獲得してきた知識と経験してきた体験を通じて Engineering を上手く実践していくためのプラクティスを解説してきました。書いてきた内容を改めて振り返ってみて、著者が重要だと思っている事項と、それらに対するプラクティス群の前提となっている事柄を、3つの原理と5つの原則にまとめてみました。

3つの原理
- 因果応報、無から有は生じない
- 構造の定義(概念モデル)は ものごと の理解を促進する
- 規模が変わると、最適な技法も変わる
5つの原則
- 科学的見地に基づいた合理的な思考
- 適切な枠組みに基づいた、段階的なステップアップ
- 作業は、中身と見栄えの掛け算として考える
- 定型業務は可能な限り自動化し、直接工数の割合を最大化
- 局所的な最適化ではなく、全体の最適化を目指す

チャレンジャーに健闘を祈りながら、キーボードから手を離すことにします。

Take it easy and Good Luck !

この記事が気に入ったらサポートをしてみませんか?