非機能要件と向き合おう！：第2章「目標を品質に近づける技術」


# はじめに
https://qiita.com/wolfmagnate/items/d9a2570d239edd2a8daa

目標を品質に近づけるとは、非機能要件における本質的な困難を解決する技術です。
より分かりやすく**品質向上につながる目標を立てる技術**と言い換えることができます。

意味のない数値を追いかけて疲弊しないための手法です。

**いいね、ストックをよろしくお願いします！**

# ユーザー目線を忘れない
品質向上に近い目標にするための最重要ポイントは、**ユーザー目線を忘れない**ことです。

<details open><summary>ユーザー目線からの測定手法の例</summary>

- 稼働中のシステムについて、ユーザーの行動シナリオに合わせてパフォーマンス測定を行う
- 実際にユーザーが使っている様子を見て、使うのに苦労している機能、使われていない機能をチェックする
- 本番稼働中のシステムについて、ユーザーがどの程度の機能を使えているか信頼性を測定するコードを追加する
- ペネトレーションテストを実施する
- ユーザーインタビューにより、実際に抱えている問題・ユーザーの置かれている環境を理解する
- 実際の開発現場でのFour Keysなどの開発速度を測定する
</details>

非機能要件は分解ができません。**最終的な品質は、全てのパーツを結合した本番環境で実際にユーザーが操作をしている場所にのみ存在します**。他の場所にあるのは、全て不完全なユーザー目線の再現です。目標はなるべく現実のユーザー環境に近づけるべきです。

:::note
**ユーザー目線を忘れない**
最終的な品質は、現場・現在・現物を見ないと分からない。できる限りリアルな環境で測定した目標を使うべきである。
:::

「カオスエンジニアリング」では、複雑すぎて脳内に収まらないシステム全体の信頼性を理解するために、（壊滅的な被害を避けるよう細心の注意を払いながら）**本番環境を使って理解する**ことの重要性が述べられています。

https://www.oreilly.co.jp/books/9784873119885/

# 目標の測定コストを下げる
ユーザー目線の目標は理想的ですが、本番環境の測定は一般にコストが高いです。そのため、なるべく時間的・金銭的コストを下げる技術が必要です。

## 本番環境での検証コストを下げる

様々な工夫をすることで、本番での検証が容易になります。コストの下げ方は具体的な非機能要件に依存します。例えば、保守性については現場で動いているコードへのアクセスが極めて容易なので特に工夫は必要ないですが、UXについては様々な工夫が提案されています。

<details open><summary>本番環境を安価に利用するための工夫の例</summary>

- 事前にユーザーとの関係性を構築しておくことで、コミュニケーションを増やせ、ユーザー目線の測定・ヒアリングを安価に行えるようにする
- システムの提供形態をクラウドにすれば、自チームでコントロールできるインフラ上でシステムが動作するので、本番環境での測定が容易になる
- システムに「改善のためにデータを送信する」というオプションを用意して、本番環境でのユーザーデータを収集する
</details>

:::note
**本番環境のコスト**
本番環境は最高の目標の測定対象なので、本番環境を使った測定のために必要な投資を惜しまないべきである。
ただし、場合によってはコストがかさむので、頻度を調整したり工夫したりしてコスパを追求する必要がある。
:::

## 安価な偽の環境を用意する
偽の環境を利用した目標は、結局のところ偽物なので品質との関連性は低いです。しかし、コストパフォーマンスの観点から補助的に採用することも考えられます。また、ある程度のコストをかけて偽の環境を現実に近づける手法も提案されています。

- ユーザー価値の提供度合いをシミュレートするために、紙芝居を作ってユーザーの反応を目標にする
- パフォーマンス・信頼性をシミュレートするためにステージング環境を用意する。カオスの注入など、現実に近くする手法もある

:::note
**安価な偽の環境を用意するポイント**
- 安くするために妥協する点を選ぶ
- 安い偽物の精度を高める工夫をする
:::

# 能動的な測定と受動的な測定を組み合わせる
目標は、測定方法と達成の判断基準の組み合わせです。

:::note
- **能動的な測定**：実際に人間が現場で品質を感じることで目標達成の度合いを判断する
- **受動的な測定**：機械的に数値を取得・計算・統計処理することで測定する
:::

能動的な測定は人間の本質的な直感を使って数値化が難しい内容を測定できますが、高コストです。さらに、測定の過程でメンバーが**品質に対する肌感覚を得られる**という点で貴重です。

<details open><summary>能動的な測定の例</summary>

- 実際にユーザーにシステムを使ってもらい、ストレスを感じたところ、ユーザーが操作を諦めたところを数えて必要なパフォーマンスがあるか、迷わずに操作できるUXがあるかを評価する
- 発生した障害と対応するユーザーからの苦情情報を分析して、インパクトの大きさを評価する
- 一定期間使われていないソースコードを読んでコードの構造に対してレビューを行い、保守性を評価する
</details>

受動的な測定は、安定した期間ごとで低コストで実施でき、閾値の決定や達成・未達の判断、差分の測定も簡単ですが、**そもそもの測定対象が誤っていても気づけません**。

<details open><summary>受動的な測定の例</summary>

- パフォーマンス・信頼性では、機械的に計測するコードを実装し（計装）定期的に集約・分析する基盤が一般的になっている。例えば、AWS Cloud Watchなどのサービスが提供されている
- ユーザビリティでは、機械的な判断ができるポイントが比較的少ない
- セキュリティでは、不正なログイン試行やDOS攻撃を検知・防御する仕組みが提供されている
- ユーザーの価値は、満足度のアンケートをアプリ内に表示するなどして測定できる
- 保守性では、サイクロマチック複雑度・コード行数・凝集度などの各種メトリクスが提案されている。また、未解決のLinterの警告の数なども重要な測定内容である
</details>

「システム運用アンチパターン」の第3章と第4章では、測定のベストプラクティスが書かれています。測定に限らずこの書籍には、非機能要件を理解するうえで非常に役立つ実践知が多く書かれています。

https://www.oreilly.co.jp/books/9784873119847/

**コストと精度のバランスをとりつつ、両方を組み合わせてください。**

# 継続的に目標を改善する
非機能要件において、品質向上に繋がる目標設定は、難しく、一度だけで解決することは困難です。
継続的に目標の問題点を探り、改善を加えていくべきです。
さらに、非機能要件は外部環境の影響を受けるため、仮に完璧な目標が作れたとしても、来週には完璧ではなくなります。**変化に対応する**ことが必要なのです。

:::note
**仮説検証フレームワークを活用した目標改善**
目標はあくまでその時点で最適だろうと考えている**仮説**であり、継続的な改善が必要である。
ユーザー・本番環境・現場に触れて、次の手順を繰り返す。

- **探索**：現場の情報を収集し、よりよい目標を作成する
- **検証**：作成した目標が実際に品質を反映するか検証し、問題点を発見する
:::

このフレームワークについては、「アジャイルなプロダクトづくり」で詳しく解説されています。

https://book.impress.co.jp/books/1123101101

より汎用的な思考のフレームワークとして、「仮説思考」という書籍も有名です。

https://www.amazon.co.jp/dp/4492555552

## 探索
探索とは、より良い仮説を作るために情報収集することです。
まだ知らない内容を見つける作業です。知らないことを探索するのですから、当然事前に調べる内容の詳細はわかりません。
体験、観察、肌感覚を重視し、関連する情報を全て見逃さないように、偶然の発見を見逃さないようにしましょう。

- 生のデータを観察する
- 実際の挙動を体験する

探索の結果は、改善された新しい仮説です。そのため、必ず現時点の仮説を明確に理解してから探索を行ってください。何も考えずに漫然と情報収集しても効果は薄いです。

:::note
**探索のポイント**
- 幅広く情報を収集する
- 肌感覚を重視する
- 現在の仮説を理解してから行う
:::

## 検証
検証とは、仮説の問題点を認識することです。すでに存在する目標（=仮説）を調べる作業ですから、事前に調べる内容を詳細に理解しているはずです。したがって、ある程度の検証計画を立てることができます。効果的な検証方法を選んでください。

- 運用者の意見：特に、能動的に測定する目標の場合、測定者の意見が参考になります
- ユーザーの意見：現状の不満、問題点などから、現時点の目標が捉えきれていない品質が明らかになるかもしれません
- データ：仮説が正しいかを判断するデータが測定できるなら、積極的に活用しましょう

検証の結果は、現状の仮説の問題点です。具体的には、仮説のどの部分にどのような修正が必要なのかです。この情報を元に、次に探索を行う領域を決定することができます。

:::note
**検証のポイント**
- 現在の仮説をもとに、効果的・計画的・科学的に検証の方法を決める
- 具体的な情報収集につながるよう、現在の仮説の問題を明確にする
:::

# ありがちなミス：品質の裏付けがない目標
ここまでの解説で**目標自体には意味がなく、目標の意味はその背後にある品質によって決定づけられる**ことを強調してきました。

しかし、非機能要件の品質は見えない存在です。したがって、品質と目標の関連性が見えなくなってしまい、ただ目標値だけを追い求めるという本末転倒な状況に陥りやすいです。

また、理屈の上では品質を意識した目標だったとしても、目標が継続的に改善されていない場合、最初にはあったはずの品質と目標の関連性は、時間とともに大きく変化し、形骸化している可能性があります。

<details open><summary>形骸化した目標の例</summary>

- 全ページの初回レンダリング時間を300ms以内にする目標に固執し、サーバー側の最適化ばかりに注力。結果、実際は大きな画像や重いスクリプトの読み込みが遅く、ユーザー体験は改善されなかった
- 「全関数のサイクロマティック複雑度を5以下に」という指標を達成するため、無理に関数を分割した結果、関数間の依存関係が複雑になり、逆にコード全体の理解が困難になった
- 四半期ごとに新機能を3件以上追加する目標に固執し、ユーザーのニーズと乖離した機能を次々に実装。結果、プロダクト全体の価値が希薄化した
- 年間脆弱性診断での指摘件数をゼロにするという数値目標に注力し、報告書上の指摘を隠蔽する対応が行われ、本質的なセキュリティ対策が疎かになった
- 1年前のユーザー調査から得られたクリック数を2回に減らすという目標を改善せずに機能追加を勧めた結果、必要な情報を一画面に詰め込み過ぎたため、情報過多でユーザーが迷い、直感的な操作性が損なわれた

</details>

品質と目標の関連性が失われてしまうアンチパターンについては、「ゾンビスクラムサバイバルガイド」に詳しく書かれています。

https://www.maruzenjunkudo.co.jp/products/9784621307397

目標を達成しようと努力するメンバーは必ず、どうしてその目標が品質を達成するのかについて理解しておく必要があります。なぜなら、目標の改善点をもっともよく考察・指摘できるのは、目標達成のために動いたメンバーだからです。

:::note
**目標と品質の関連性を保とう**
- 目標を達成しようとするメンバー**全員**が、目標自体に意味はないことを理解し、目標の達成のために本質的でない作業をして誤魔化さないようにする
- 継続的に現場に触れることで、品質についての肌感覚を持っているべきである
- メンバーからの目標の不合理を反映するべきである
:::

# おわりに

品質と目標の関連性は、一番目に見えづらい、言語化しづらい部分です。頑張って目標を設定しても、それが正しいかのフィードバックが簡単に得られないことも難しい点です。
しばらくは生成AIでも対応できない領域だと考えられます。

本記事で解説した手法を活用して、見えない部分の品質を高めていきましょう。

https://qiita.com/wolfmagnate/items/d843d1410b6f290eaba6