野狐消暇録

所感を記す

要件を整理することでシステムの品質を上げる。

ソフトウェア要求をヒアリングしていくと、要求を出した人達が何をしたいのかが分かってくる。要求を良く理解する事で、システム要件が整理でき、結果としてシステムの品質を上げられる。以下に成功例と失敗例を挙げる。

【成功事例】チラシ同梱機能の修正①

商品発送時に宣伝チラシを同梱するシステムを改修する事になった。最初にヒアリングしたとき、顧客が出してきたシステム要件は以下であった。

■ 最初のシステム要件

チラシA、B、CをまとめてチラシXにしたので、システムもそれに合わせて修正してほしい。

■ 修正前のシステム

調べてみると、システムは以下の状況であった。

〇 商品ごとに同梱するチラシを決めて同梱を行う。

  • 商品A → チラシA
  • 商品B → チラシB
  • 商品C → チラシC

これを顧客の出してきた要件そのままに修正した場合、おそらく以下になるだろう。

■ 修正後のシステム(案1)

  • 商品A → チラシX
  • 商品B → チラシX
  • 商品C → チラシX

■ 整理後のシステム要件

しかし、もうちょっと要求を掘り下げてみると、システム要件を整理できる事が分かった。整理した後のシステム要件は以下である。

  • 定期お届け商品発送時にチラシXを同梱する。

商品A,B,Cは全て定期お届け商品であり、それらの商品の発送時に同梱するチラシをチラシXに統一した、という事であった。

■ 修正後のシステム(案2)

整理後のシステム要件に従えば、そもそも商品ごとに入れるチラシではなく、定期お届け商品に入れるチラシという事になるので、システムの改修は以下になるだろう。

  • 定期お届け商品(商品A,商品B,商品C, …) → チラシX

案1と比較したとき、この方式には以下の利点がある。

  • 商品ではなく、定期お届け商品という商品カテゴリにチラシが紐付いている事が明確になる。
  • 今後新しい商品が販売されても、カテゴリだけ決めれば自動的にチラシの同梱要否が決定されるため、変更に強い。
  • チラシを同梱するべきか否かの判定ロジックが一か所にまとまるので、システムがシンプルになり、改修にかかる工数を削減できる。

■ まとめ

顧客の要求をヒアリングする中で、システム要件を整理でき、案2にたどり着いた。案2の一番良い点は、顧客の要求をそのまま実装している点である。

【失敗事例】チラシ同梱機能の修正②

これは焦って実装して失敗した例である。

■ システム要件

定期お届け商品をお届けするにあたり、3回発送するごとに他の商品を紹介するチラシを同梱してほしい。

■ 修正前のシステム

定期お届け商品の発送回数を指定して、チラシを同梱する機能があった。

■ 修正後のシステム

発送回数指定のチラシ同梱機能に、今回向けの指定を追加する事にした。

追加する指定回数は以下である。

・3,6,9,12,15

こうする事で5回は同梱できる。5回以上の定期発送が発生したら、またデータ指定を追加する。

■ この修正のデメリット

  • システム要件と実装があっていない。「3回ごと」というシステム要件を実装するのは容易であるにも関わらず、「指定回数でチラシを同梱する」という別の機能を使っているため、一々データを正しく設定しなければならなくなっている。これでは手間がかかり、間違いが起きる可能性も高くなる。それはまた、保守要員の作業が増える事でもあるので、人件費という形で費用もかかる。
  • 修正後の同梱仕様を画面で確認すると、指定した回数が画面上に羅列され、「3回ごとに同梱する」という設定になっているのか確認できない。3回ごとなのかどうか、自分で数えて判断する必要がある。

■ なぜ失敗したか

顧客の要求をシステム上で表現できていない事が失敗の原因である。システム要件を実現するために別の機能を代用したため、手間がかかり、かつ分かりにくいシステムになってしまった。

幸い、このシステムを修正する事は容易であり、単に指定回数ごとにチラシを同梱する機能を追加してやれば良い。

【全体のまとめ】

システム要件を整理する事が根本的なリファクタリングになる。

システムが複雑になっている要因を以下のふたつに分けて考えてみる。

1. システム要件自体の複雑性

上記の例のように、システム要件を整理する。これはシステム要件のリファクタリングであると言っても良いと思う。

 2. ソースコードが整理されていない

システム要件を素直に表現したコードにしていくのが大切であると思う。後はいわゆるコードリファクタリングであるが、この記事の目的ではないから省略する。

作業をまとめて実施することで、ソフトウェア開発の効率を上げる。

ソフトウェア開発を進めるに当たり、開発時のコントロールによってある程度開発効率を上げる事ができる。結論を先に書くと、開発効率を上げるには、作業をなるべくまとめて実施する。これから書く例は、2,3人で回す小規模な開発案件を念頭に置いている。

開発効率を落とす事柄

まず、開発効率が落ちる例を挙げる。これらは作業を分けて実施する事により、効率が落ちる例である。

■作業の分担

開発作業を一人で担当した場合、開発チーム内のコミュニケーションコストはゼロである。一人しか要員がいなければ、当然そうなる。しかし、要員が二人、三人と増えると、コミュニケーションコストも要員の増加に従って増える。これを規模の不経済と言う。この不経済を防ぐには、ひとつの案件に対する担当人数を可能な範囲で少なくすると良い。従って、一人で担当できる案件を二人に分割してはならない。ただし、他人にレビューしてもらったり、追加でテストしてもらう事で品質が上がる事がある。そうした活動が品質改善に役立つ場合、それは良いと思う。自分がここで考えているのは、途中で他の人に案件を渡したりするケースである。これは無駄なコストが発生するから、こうしたケースが起きないようにしなければならない。

■リリースの分割

開発が納期に間に合わなくなり、リリースを分割する事が良くある。一次リリース、二次リリースに分割してリリースするのだ。これが非効率的である事については、スティーブ・マコネルの『ソフトウェア見積もり』にも書いてある。リリースを分割すると、後で捨てることになる暫定版を作る工数がかかる。更に暫定版にバグが出れば、そのバグを直す工数もかかる。これはリリースが一回であれば、不要だった工数である。そのため、急いで作る必要があるときにリリースを分割するのは有効な方策であるが、開発効率は落ちるため、リリース分割をしなくて済むのが最善である。そのためには納期に間に合う必要があり、余裕を持ったスケジューリングが必要になる。

開発効率を上げる事柄

これらは作業をまとめて実施することにより、効率を上げる例である。

■ 案件に関わる箇所をリファクタリングする

リファクタリングを案件の対応作業と一緒に実施すると、影響調査とテストが一度で済むため、修正作業とリファクタリングをそれぞれ単独で実施した場合よりもコストが下がる。そのため、リファクタリングが必要な箇所を予めリストアップし、気付いたらリストに追記するようにしておくと良い。こうすることで、何かで修正作業が発生したとき、修正対象機能の周りでリファクタリングする箇所があるかどうか、調べる事ができる。

■ 担当案件に関わる箇所をドキュメントにまとめる

プログラミングでは、細かい仕様やソースコードの構成など、その場では理解しているものの、しばらく経つとすっかり忘れてしまうような事柄がある。時間を経てから作業を再開しようとすると、同じ疑問についてもう一度調べたり、一度依頼主から聞いたことを再度確認する必要が出てきたりして、非効率である。そのため、ある案件で理解した設計仕様や要件などは、なるべくドキュメントにしてまとめておくと良い。

開発効率に関するまとめ

一言でまとめれば、「なるべくまとめて作業をする」ということである。

  • リリース分割や作業分担は、作業を分割する事で効率を下げる。
  • リファクタリングやドキュメント作成を案件対応と一緒に実施する事は、作業をまとめる事で効率を上げる。

これらを実施するには、作業期限に余裕がある事が重要である。

逆に言えば、期限に余裕がある場合は、上記を実施する。

『ソフトウェア見積り 人月の暗黙知を解き明かす』(スティーブ・マコネル著)のノート(5章以降)

5章以降の話は、本格的な規模の大きいプロジェクトでは使えそうだ。しかし、自分の所属する開発チームは7人日程度の工数が最大だ。そのため、あまり5章以降の話ですぐに生かせそうな話題がない。そこで、自分が気になったポイントをピックアップしてここに書いておく。

■見積もりでは「数えて、計算して、判断する」

数える

調査すると言い換えても良い。そもそも、見積もりは分からないものに対して用いる手法であり、調査して分かるのであれば、見積もりよりもずっと望ましい。

数えられるもの

要求の数機能の数、画面数、出力するレポートの種類数など

数えられるもののうち、開発工数と関連が深いものを選んで、数えること。

計算する

 数えたものひとつ当たりの工数 × 数えたものの数

判断する

ここで云う判断とは、専門家の経験による見解とでもいうべきものである。これはなるべく用いてはならない。理由は、「即興の見積もりをしない」事と同じで、頼りにならないからである。

■当該開発チームの過去の実績データを参照する

一番良いのは、開発初期の実績データを使う事だが、これは自分のチームの開発だと、開発規模が小さ過ぎて、あまり使えない。実績データが出てから数日でその案件が終わってしまうからだ。しかし、長期化した場合は、その時までにかかった実績時間を元に見積もりを立てるのが良い。開発が初期の見積もりよりも遅れていれば、次の式で計算する。

残作業の初期見積もり ×(完了作業の実績工数 / 完了作業の見積もり工数

例えば、既に終わった作業が初期見積もりの1.3倍の工数がかかっていれば、今後の作業にも同じだけの係数を掛けて計算する。間違えても「今後の作業はハイペースで進む!」などと想定してはならない。

開発初期の実績データがまだ出ていない状況下では、過去の開発の実績値を参照すること。

■実績データの収集

下記の優先度で収集する。月日が経てば何も分からなくなってしまう。

  1. プロジェクトの進行中に収集する。
  2. プロジェクトが終わってなるべく早い時期に収集する。

■見積もり誤差の計算式

自分の見積りの相対誤差の大きさ(MRE:MagnitudeofRelativeError)を計算する(Conte,Dunsmore,andShen1986)。MREの計算には次の公式を使用する。(Kindleの位置No.2352-2353)

 MRE = (実際の結果  -  見積もり結果) ÷ 実際の結果

実績をベースにフィードバックループを作り、長期的に見積もりを改善すること。

大数の法則の利用

複数の小さな見積もりを作って足すと、大き過ぎる見積もりと小さすぎる見積もりが打ち消し合って、全体としての見積もり精度が改善する。これを大数の法則と呼ぶ。大数の法則の恩恵を受けると良い。この法則の恩恵を受けるには、5~10個の見積もりが要る。

■アクティビティの計上漏れを防ぐには?

アクティビティの一覧を作ると良い。過去の実績データからアクティビティを取り出して一覧にしておき、今後の開発プロジェクトを見積もる時に参照する。こうすることで、「アクティビティを思い付かなかった」「検討し忘れた」という事態を防げる。

つまり、アクティビティも記録していく必要がある。

改修時の影響範囲についても、記録を取っていくことで、影響調査漏れを防げるかもしれない。

■レビューによる精度の向上

以下の手順で実施する。

  1. 複数の専門家が個別に、互いに相談せずに見積もりを行う。
  2. 出した見積もりを持ち寄り、互いの相違点について話し合い、見積もり幅の上端と下端を決める。

上記手順「2.」の中で、以下を実施してはならない。

  • 単純に持ち寄った見積もりの平均を取る。
  • 投票で決める。

このレビューにより、一人で見積もりを取った時に比べ、見積もり誤差を約半分に減らす事ができる。

 

『ソフトウェア見積り 人月の暗黙知を解き明かす』(スティーブ・マコネル著)のノート(4章)

■見積もり誤差の発生要因

  • プロジェクトに関する不正確な情報
  • 開発チームに関する不正確な情報
  • プロジェクトの混乱
    → 移動するターゲットの見積もりは困難であるため
  • 見積りプロセスが適切でない

■ 見積もりの不確実性はプロジェクトの決定事項に依存する 

f:id:nogitsune413:20190203132408p:plain

不確実性のコーン。決定事項が増えるに従い、不確実性が減少する。(Kindleの位置No.1145付近)

つまり、何も決まっていないプロジェクトについていくら見積もり作業をしても、到達できる確実性には限界があり、不確実性は残る。下記の表にあるように、プロジェクトの初期に不確実性を取り除く決定が行われるので、これらの作業が漏れなく行えれば、見積もりの精度は上がってくる。

f:id:nogitsune413:20190203133507p:plain

カレンダー時間を横軸に取った表。プロジェクトの初期に不確実性が急速に収束するのが分かる。(Kindleの位置No.1162付近)

 このバージョンのコーンからわかるように、見積りの正確性はプロジェクトの期間の最初の30%で急速に改善され、±4倍から±1.25倍に減少する。(Kindleの位置No.1170-1171)

ただし、この表はプロジェクトを進める中で、適宜必要とされる意思決定が確実になされたことが前提になっている。これらの決定が有効でないと、見積もり誤差は以下になる。

f:id:nogitsune413:20190203134355p:plain

プロジェクトにおいて適切な意思決定がなされなかったケースでは、灰色に塗った部分のようになる。つまり不確実性がほとんど減らないのだ。(Kindleの位置No.1187付近)

■不確実性が高い状況での見積もりの出し方

上記の研究結果を実際のプロジェクトに反映するには、以下のような表が有効である。それは、プロジェクトの置かれた状況に合わせて、最初に出した「一番ありそうな見積もり」に対して、決めておいた係数をかけるという方法である。

f:id:nogitsune413:20190203134922p:plain

プロジェクトの状況に合わせ、初期見積もりに係数を掛けて不確実性を見積もりに反映する。(Kindleの位置No.1202)

この係数は実際のプロジェクトや開発チームによって変わりそうだが、考え方として有効だということだろう。例えば、「新しいECサイトを立ち上げてお茶を販売する」というケースでは、「初期コンセプト」の段階に相当しそうである。この段階で見積もりを出すのは難しいが、上記のやり方に従えば、かなり幅のある見積もりにはなるものの、一応の数字を出せることになる。「何も分かりません」という回答よりずっと良い。

有意義なコミットメントは、プロジェクトの前半(進路のおよそ30%)で行うことが可能であり、適切である。(Kindleの位置No.1221-1222)

それ以前のコミットメントにはあまり意味がないということ。役に立てるには見積もりが荒すぎるのだ。

■プロジェクトの不正確な情報への対策

プロジェクトの情報が不正確である例

  • 要求の見落とし→見逃されていた影響箇所の発見
  • アクティビティの見落とし→開発環境構築など、必要な作業の計上漏れ

アクティビティの見落としを防ぐには、過去の記録を調べると良い。また、今後のために記録を残すことはもちろん有用である。何にどのぐらいかかったかが分かれば、予測の上で有用である。

■偏見への対策

即興で、つまり直感だけで見積もりをしてはならない。それは不正確で役に立たないのである。そして常に楽観的になってしまう。思い付くアクティビティが少なすぎるのがおそらく原因である。ちゃんと見積もり作業を実施すること。

■見積もり精度

見積もりの正確性と出す数字の有効桁数を一致させる。

日単位でしか意味がないのに、34時間15分~40時間45分などという見積もりを出したら、15分単位の精度で見積もりを出したと勘違いされる。

 

『ソフトウェア見積り 人月の暗黙知を解き明かす』(スティーブ・マコネル著)のノート(1章~3章)

この素晴らしい本の内容を忘れてはいけない。

そういう強い思いから、ここに自分が特に覚えておきたいと思う、ソフトウェア見積もり技術の要点を書き記す。

■見積もり、ターゲット、コミットメント

○ 見積もり

ソフトウェアプロジェクトにかかる以下を予測することである。

  • コスト
  • 期間

○ ターゲット

ビジネス上の目標である。

(例)

  • ○○日までにこの機能を完成させたい
  • ××円以内のコストで次期バージョンをリリースしたい

○ コミットメント

以下についての約束。

  • 機能
  • 納品日
  • 品質

■見積もりと計画の違い

○ 見積もり

 作成するソフトウェアの規模に応じて決まってくる必要人員、必要日数のこと。目的の機能をリリースするために必要なコストを知るために行う。

○ 計画

 ターゲットを達成するためのプロセスのこと。見積もりで出したコストが高過ぎる場合に重要度の低い機能を削ったり、見積もったスケジュールで納品が間に合わない場合に最小限の機能で一次リリースを行い、重要度の低い機能を二次リリースに回したりする。見積もり情報を参照しながら、適切な計画を立てる。

■見積もりには幅を持たせよ

この機能は14日間で完成する見込み、というようなシングルポイントの見積もりをしてはいけない。この機能は12日間~16日間で完成する見込み、と言う風に見積もりに幅を持たせること。

  • シングルポイントの見積もり:14日間で完成
  • 幅のある見積もり:12日間~16日間で完成

■良い見積もりの指標

『ソフトウェア見積もり』からそのまま引用する。

良い見積りのアプローチとは、実績値の75%のケースで誤差が25%以内に収まる見積りを提供することである(Conte、Dunsmore、Shen1986)。

ここで書かれている誤差25%とは、見積もったスケジュールの全期間を100%と見たときの値である。例えば、見積もり10日間のプロジェクトがあったとすると以下である。

 8日間で完成:-20%の誤差

 13日間で完成:+30%の誤差

つまり、10日間のプロジェクトなら、7.5日~12.5日の期間でプロジェクトが完了すれば、誤差25%以内に収まったことになる。

> 実績値の75%のケース

こちらは、見積もったプロジェクトが複数あるとして、それら複数のプロジェクトのうち、75%のケースで目標値を達したら、良い見積もりと見做すという意味である。

例えば、見積もったプロジェクトが100件あるとすると、75件で目標値である誤差25%をクリアしている必要がある。

■見積もりの目的

良い見積りとは、プロジェクトの責任者がプロジェクトのターゲットを達成するためのコントロールを行ううえで、適正な意思決定ができる明確な視点を提供する見積りである。(Kindleの位置No.707-708)

 見積もりの目的は、プロジェクトマネジメントの基礎となる情報を提供することにあると思う。この情報を元に、計画を立て、人員を割り当て、提供する機能を決定していくことになる。従って、見積もりは正確である必要がある。しかし、それは厳密さを要求するものではなく、上記の目的を達するために有用な程度の正確さがあれば良い。

■プロジェクトコントロールによるリカバリの限界

ビジネス上のターゲットに対して、スケジュールおよびそのターゲット達成に必要な工数のギャップが大きすぎる場合は、問題として認識すべきである。私の経験では、初期ターゲットと初期見積りの差異がおよそ20%以内であれば、プロジェクトマネージャが、仕様項目、スケジュール、チームの人数などのパラメータをやりくりして、プロジェクトのビジネスゴールを達成できる余地がある。(Kindleの位置No.687-691)

つまりターゲットと見積もりに20%以上の差異がある場合、プロジェクトコントロールではリカバリできない。それは「無理な計画」である。

■過少見積もりと過大見積もり

○ 過少見積もりによる悪影響

  • プロジェクト計画の有効性が減少する (Kindleの位置No.857)
  • 予定どおりに完了する機会が統計的に減少する (Kindleの位置No.867)
  • 必要な作業が行えなくなる
    (例)要求開発、要件定義、テスト
    要するに最低限必要な作業であるコーディング以外の作業をすっ飛ばすために、開発作業の後半で多くの手戻りに襲われたり、リリース後のバグに苦しめられたりすることになる。
  • スケジュール遅延による不要な作業が発生する
    暫定版のリリースや、顧客への謝罪と打ち合わせ、再スケジュールなど

■見積もりに関する興味深い統計調査結果

・ソフトウェアの見積りは、しばしば100%あるいはそれ以上に不正確であることが、多くの調査でわかっている(Lawlis,Flowe,andThordahl1995;Jones1998;StandishGroup2004;ISBSG2005)。(Kindleの位置No.863-864)

・開発者が作る見積りは、一般に実際の工数よりも20〜30%低くなるものだ(vanGenuchten1991)。(Kindleの位置No.868)

・Standishグループは「カオスレポート(TheChaosReport)」と呼ばれる2年ごとの調査を発行している。これは、ソフトウェアプロジェクトの実績を記述したものだ。2004年のレポートによると、プロジェクトの54%が遅れ、18%が完全に失敗し、当初の予定期間と予算内で開発されたのは28%とされている。(中略)Standishグループのデータで注目すべきなのは、「早く終わったプロジェクト」については、そのカテゴリさえないということだ。起こり得る最良の実績は、期待に沿うこと(予定どおり/予算どおり)なのだ。その他の実績は、すべてそこからの下り坂だけだ。(Kindleの位置No.914-920)

■見積もりの困難性

大きな規模の開発の方が、小さな規模の開発よりも失敗しやすい。

また、見積もりは「もしかしたら終わらせることができる最も早い日」(DeMarcoによる「見積り」の定義)になりやすい。つまり実行可能な最小コストになってしまうということである。

■正確な見積もりの利点

  • 状況が可視化される
  • 品質の向上
    ソフトウェアのエラーの約40%はストレスによって引き起こされることがわかっている。これらのエラーは、適切にスケジューリングをして、開発者にあまりストレスを及ぼさないようにすれば、回避できるものだ(Glass1994)。スケジュールが極端に切迫している場合、そこでリリースされたソフトウェアは、切迫していない状況で開発されたソフトウェアに比べて、約4倍もの欠陥が報告されている(Jones1994)。理由の1つは、チームがソフトウェアをリリースするために、予定期間内に必ず完成しなければならない機能を、間に合わせのバージョンで実装するということだ。過度のスケジュールの切迫は、きわめて費用がかかり間違いの発生しやすいモジュールができる最大の原因であることがわかっている(Jones1997)。(Kindleの位置No.968-974)
  • ソフトウェア以外の業務部門との連携が良くなる (Kindleの位置No.978)
    これは最近実感している。連携がスムーズになると共に開発部門に対する信頼が向上するので、精神衛生上良い。
  • 予算が良くなる。
    ソフト開発にかかる費用の見積もりが正確になる。言うまでもなく、開発コストが見通せるようになるからだ。
  • 早期にリスク情報が得られる
    見積もりをした段階で、スケジュールが間に合わない、費用が掛かり過ぎるなどのリスクが見えた場合、その場で何かしらの手を打つことができる。これは見積もりなしに開発を始めて、ターゲットに到達しないのが誰の目にも明らかになってからどたばたするより、ずっと有難い状況だ。

これらの利点は要するに、「これから起きる事が分かっていたら、こんな事ができる」という話である。地図を手に旅をするのと、地図なしに旅をすることの違いだ。見積もりは旅人に地図を提供する。

 

 

 

 

 

 

 

表現形式と表現内容

音楽と一口に言っても、様々な音楽がある。だから、音楽が好きと言っても、Jazzが好きな人もいれば、クラシックが好きな人もいる。

人の好き嫌いを知るには、音楽や絵画といったジャンルのどれが好きかを聞くのではなく、どんな音楽が好きか、どんな絵画が好きかを聞いた方が良い。

Jazzが好きな人なら、服もお洒落な服を着ていそうだし、ヒップホップが好きな人は、ヒップホップ系のファッションをしていそうに思う。

要するに、自分の好きな世界観や生き方が、音楽や絵画やイラスト、ファッションに表れているのであって、ジャンルは表現の形式に過ぎない。

とはいえ、表現の形式に表現内容が表れている事もまた、自然な事ではある。和歌が五七五七七で、俳句が五七五なのは、なんとなく納得がいく。和歌で普通表現されるような世界は、五七五ではちょっと短いのかもしれない。しかし、それも一応の事であって、日本人が漢詩を作ると、やっぱり中国人の作った詩とは違ってくる。形式が同じであっても、内容によって感じが変わってくるのである。

自分で何かの創作をするときに気を付けるべきことは、まさにそこだろう。漢詩だから、という理由で、中国人の詩の真似をしてはならないのである。飽くまで、自分で詩を書かねばならない。現代の詩はこんな感じだ、というのも指標にはならない。

なんでも創作というのはそうで、その世界のやり方というのはあるにしろ、表現内容というのは自由であり、自由に自分で作るのが一番良いのである。

それが、のびのびとした創作なのである。

袖を詰める

服をオーダーメイドするのは良い贅沢だと思う。スーツを買うときズボンの裾を上げてもらうが、袖も丈を合わせてもらえることを知った。スーツの袖は大抵長めに作ってあるそうで、奥さんがスーツを西友で買ったら、袖が長すぎて手が半分隠れてしまった。それで詰めてもらったのだが、なかなか良い。問題は詰めてもらっている間、スーツが着れない事である。入り用になってから買いに行くと、袖丈を詰めてもらっている余裕がない。妻の場合は一旦長い袖のまま一月ほど働いて、スーツを着なくて良い期間ができたら、その隙に上着を預けにいった。それで一週間ちょっとで袖が丁度良い丈になった上着が返ってきて、着てみたら果たしてぴったりだった。確か三千円ほどだったか。高い気もするが、贅沢として良いなと思った。