見出し画像

ユーザー体験を高めるためのエンジニアリングと効率性を高めるためのエンジニアリング、その両方の視点を持つ

エンジニアたちの時間を機能開発にばかり割いていると、彼らの生産性や業務効率が落ちてしまいます。これが、自社ソフトウェアプロダクト開発の難しいところです。

ところが、プロダクト開発に関わっていても、それに気付いていない関係者が意外と多いように感じます。その背景には、エンジニアリング業務に対しての不理解があるのではないでしょうか。

ユーザー体験の向上と効率性の向上。エンジニアリング業務は、この2つの目的に分けられます。前者ばかりに気を取られていると、徐々に効率性が落ちていきます。だから、後者に向けた活動によって効率性を回復したり、向上させたりすることが欠かせません。逆に、後者の活動にばかり時間を割いていると、いつまで経ってもプロダクトのユーザー体験は高まりません。

それでは、両者をどのようにバランスさせてエンジニアリング業務を遂行すれば良いのか。それを検討する前に、それぞれの目的に対してどのような活動があるのかを掘り下げてみる必要がありそうです。

エンジニアリング業務における2つの目的とその活動

優れた体験をユーザーに提供すること。それが、自社ソフトウェアプロダクトを市場展開する組織において、最も優先度の高い関心事です。ユーザー体験が、プロダクトに対するユーザーにとっての価値を決定づけるからです。そのユーザー価値を高め、さらにビジネス価値へと変換する。これこそが組織が継続的に追求するミッションです。

組織の中で、エンジニアたちが有する生産力のほとんどは、「機能」といった「プロダクトの振る舞い」を形にすることに投じられます。ユーザーが振る舞いに触れることで、ユーザー体験が生じるからです。

この点だけを見れば、振る舞いの実現に生産力を集中させる判断が、実に明快で合理的であるように感じられます。

しかし、生産力を集中させたからといって、振る舞いをより早く、より多く形にできるわけではありません。ソフトウェアシステムは、開発を続けるほど肥大化、複雑化します。また、ユーザーが増えれば、システムへのアクセス増加やデータ量の増加も起こり得ます。そういった傾向が進むほど、エンジニアにとって、ソフトウェアシステムは扱いにくいものになっていくのです。そこに注意を向けず、振る舞いの実現にばかり集中していると、エンジニアたちの生産性や業務効率は悪化し続けるばかりです。

これらのことから、エンジニアリング業務には2つの目的を見いだすことができます。1つは、ユーザー体験のための振る舞いの実現。もう1つは、効率性のための振る舞い以外の整備です。

前者はユーザーに知覚できる対象であり、後者は知覚できない対象です。シンプルに、「見える価値」と「見えない価値」と言い換えることにしましょう。見える価値がなければユーザー体験が生まれず、見えない価値がなければ見える価値を大きくすることが困難になっていく。そういう関係です。

そしてこれは、ソフトウェア開発業務だけに限った話ではありません。エンジニアリング業務における3つの業務機能である「ソフトウェア開発」「ソフトウェア保守」「システム運用」のいずれにおいても言えることです。

ソフトウェア開発業務では、「機能開発」によってプロダクトに見える価値を追加します。「内部設計/アーキテクティング」は、見えない価値を作り上げる活動です。

ソフトウェア保守業務では、「欠陥の修正」が見える価値を扱い、「リファクタリング/リアーキテクティング」が見えない価値を扱います。「適応」と呼ばれる保守業務では、見える価値、見えない価値のいずれも扱います。

システム運用業務では、「信頼性の維持・向上」が見える価値を、「トイルの削減」が見えない価値を扱います。

機能開発

機能追加や機能改善といった「機能開発」は、プロダクトの振る舞いの追加や変更を行うソフトウェア開発業務です(「完全化保守」として扱う場合もあります)。

機能開発によってプロダクトに加えられた変更は、リリースを経ることで、ユーザー体験に影響を与えます。優れた体験を提供できたなら、プロダクトに対するユーザーの価値は高まります。未利用の人たちに対しては、プロダクトの利用動機を生じさるものにもなり得ます。だからこそ、自社プロダクトに対する組織のフォーカスは、機能開発にばかり向けられます。

ところで、「機能開発」と言っても、そこには機能面だけでなく、非機能面も含まれます。その中でも外部品質に含まれるような非機能面は、ユーザーから「見える」対象です。つまり、ユーザー体験を形作るものです。特に、アプリケーションのパフォーマンスや応答性は言うまでもないでしょう。

もし、リリースした新バージョンのスマートフォンアプリが、起動に20秒もの時間がかかるようになっていたら?もし、ボタンを押してからグラフが表示されるまでに10分もかかったら?もちろん、ユーザー体験は最悪です。下手をすれば、ユーザーの離反を招きかねません。

ところが、プロダクトに対するアイデアを形にしていく中でつくり手が意識するのは、機能面ばかりであるように感じます。外部品質に含まれる非機能面は、ユーザー体験に影響を与える重要な特性です。その点をあらためて意識すべきでしょう。

内部設計/アーキテクティング

機能開発は、ユーザーから見える価値を生み出しますが、開発範囲に見えない価値が含まれていないわけではありません。機能面に加え、外部品質に含まれる非機能面が見える価値の範囲だから、残りの範囲が見えない価値にあたります。外部品質に含まれない非機能面、つまりは「内部品質」です。この節で取り上げる「内部設計/アーキテクティング」は、プロダクトの振る舞いを実現するために、内部構造の品質を高める活動です。

ソフトウェア開発のやっかいなところは、内部構造の品質の良し悪しに関わらず、プロダクトに求められる振る舞いを実現できてしまう点にあります。

だったら、内部品質など気にする必要はないのではないか、と思うかもしれませんが、そういうわけにもいきません。なぜなら、内部品質(特に保守性)の悪化に伴って、ソフトウェア開発やソフトウェア保守の生産性も悪化してしまうからです。

ソフトウェアの内部品質が悪い状態のひとつとして、内部構造が複雑になることが挙げられます。ソフトウェアがこの状態に陥ると、コードの簡単な変更であっても、その対応に時間がかかるようになります。変更の影響範囲を読み解くことに時間がかかってしまったり、予想より多くの箇所に変更を加えなければならなくなったりするからです。たとえばチームの生産力が100だとしても、そのうち20ぐらいがこういった余計な手間に消費されてしまうのです。この場合、生産性は80%に落ちてしまっています。

内部品質と聞くと、その対象がソフトウェアそのものだけを指すように聞こえますが、そうではありません。ソースコード中のコメントやドキュメントが適切に存在するかもその対象です。他にも、開発にあたってのルールやガイドラインなども含まれます。いずれも適切に存在しなければ、生産性に悪い影響を与えるものばかりです。

こういった、将来の生産性悪化を未然に防ぐことが、内部設計やアーキテクティングの目的です。これらの活動が、必要十分で最適な内部構造を実現し、内部品質を高めるのです。

欠陥の修正

ソフトウェア保守業務である「欠陥の修正」は、「機能開発」と同じくユーザー体験を高めるための活動です(ここでは「欠陥の修正」に、「是正保守」「予防保守」「緊急保守」を含めます)。

欠陥の修正では、プロダクトの振る舞いを正し、外部品質を高めることで、ユーザー体験の改善に努めます。プロダクトへの新たな価値の追加ではなく、価値を下げる要素の排除を目的としているのです。

ソフトウェア開発業務による機能開発では、そのリリースまでに、そこに含まれる欠陥が全て修正されていることを保証しません。リリースに足る品質があると判断されたなら、欠陥が残っていてもリリースするからです。また、そもそも、「すべての欠陥を検出できた」なんてことを保証することができません。

こうして残された欠陥は、ソフトウェア保守業務の一環として、リリース後に粛々と修正されていきます。ここで修正される欠陥は、リリース時点で既知のものもあれば、その後に検出される未知のものも含まれます。また、本番稼働中のソフトウェアシステムにトラブルが発生した時の緊急での一次対応的な止血もあります。

欠陥の修正でも、外部品質に含まれる非機能面の考慮が必要です。修正によって著しくアプリケーションパフォーマンスが劣化するなんてことは許されません。また、そもそもパフォーマンスが悪い状態を欠陥と位置づけ、それを正すこともあります。

リファクタリング/リアーキテクティング

機能開発を進める中で、内部設計やアーキテクチャの品質を十分に高められるかどうかは、さまざまな要因が影響します。実現したいことの難易度、チームの知識やスキル、文化、組織設計、事業戦略など。そして、これらは機能開発だけでなく、欠陥の修正においても同じことが言えます。プロダクトの誤った振る舞いをその場しのぎ的な方法で修正してしまうと、内部品質が悪くなるからです。

また、たとえどんなに頑張ったとしても、プロダクトに対する変更を繰り返す中で、内部構造は徐々に複雑になり、内部品質は悪化していくものです。それに加え、同じプロダクトに長くかかわることで、より優れたアーキテクチャや内部設計に気づくこともあります。そうすると、理想の内部構造と現実の内部構造との間で乖離が生じていきます。これは、内部品質の相対的な低下と言えるでしょう。

こうして悪化してしまった内部品質を正し、生産性を取り戻そうとする活動が、ソフトウェア保守の一環として実施される「リファクタリング/リアーキテクティング」です。

リファクタリングは、プロダクトの外部の振る舞いを保ったままで、内部の構造を改善していく作業を指しています。リアーキテクティングも同様ですが、扱う対象がリファクタリングより大きくなります。

※リファクタリングはソフトウェア開発においても、アーキテクチャや内部設計の解を得るための手法として取り入れられることがあります。機能開発を進める中で、部分的に小さく実装してはリファクタリングするという手順を反復的に繰り返しながら、機能全体の実装を進めるといった手法です。

繰り返しになりますが、内部品質が悪いと機能開発や欠陥の修正の生産性が低下します。市場投入までの時間が長くなるということです。また、内部品質の悪さが生産性にどれぐらい影響を与えるかを、正確に予測することはできません。見積り精度が落ち、計画に対する予測可能性も下がるのです。

予測可能性を低下させる問題は、それだけにとどまりません。内部品質が悪いと、欠陥が増えたり、本番稼働時のトラブルが多くなります。外部品質が悪化するのです。そうなると、エンジニアたちは欠陥の修正や、突発的なトラブル対応に追われるようになります。それらの対応に割かれてしまう時間がどれだけになるのか、事前に予測することはできません。

はじめから内部品質が高ければ、これらの対応に費やす時間は不要だったはずです。このようにして生じる無駄な作業の必要性をフェイラーデマンド(failure demand)と言います。書籍『LeanとDevOpsの科学』によれば、ローパフォーマーに分類される組織は、ハイパフォーマーに対して「予定外の作業や修正作業」にかかる時間比率が6ポイントも高いそうです。

もし、ソフトウェア保守やシステム運用業務に時間が多く取られているようなら、フェイラーデマンドが発生していることを疑うべきかもしれません。逆に言えば、内部品質に気を配っていれば、ソフトウェア保守やシステム運用の負荷が下がります。その時間をソフトウェア開発にまわすことも可能になるはず。

適応

ソフトウェア保守業務には、「適応保守」というものもあります。これは、外部環境の変化にプロダクトを適応させていくものです。その目的は、ソフトウェアプロダクトが利用できる状況を保ち続けることにあります。それが、ユーザー体験を維持することや、生産性を維持・向上することにつながります。

ユーザー体験を維持するための適応保守の一例は、ユーザー側のアプリケーション動作環境の新バージョンに対応させることです。スマホやPCのOS、ウェブブラウザなどがその対象です。所有するスマホのOSをバージョンアップさせた途端、アプリが動作しなくなったりしたら、そのユーザーはがっかりしてしまうでしょう。ユーザーにそのようなネガティブな体験をさせないためにも、なるべく早く最新の環境に適応させていくことは重要です。

新しい規制や法令に適合させることも、適応保守に含まれます。たとえば、最近ではプライバシーや個人情報の取り扱いが厳しくなりつつあります。こういった変化に対応させなければ、プロダクトの提供自体が難しくなってしまいます。これも、ユーザー体験を維持するための適応保守なのです。

一方で、ユーザー体験には直接的に影響しない適応保守もあります。その代表例は、ソフトウェア内部で利用しているフレームワークやライブラリを最新バージョンに交換することです。

古いバージョンのフレームワークやライブラリを使い続けていると、様々な問題を抱えることになります。

まっ先に思い浮かぶ問題は、いずれそのバージョンがサポートされなくなることでしょう。ライブラリに脆弱性がみつかっても、パッチが提供されないということです。そうなると、脆弱性のある箇所を自分たちで修正しなければならなくなってしまいます。このような作業の存在は、ソフトウェア保守業務の負担となってしまいます。

また、バージョンアップによって本来得られるはずの生産性を放棄することになるかもしれません。開発効率を高めるために有用な機能が、フレームワークやライブラリの新バージョンに追加されることがあるからです。

これらのことから、旧バージョンのフレームワークやライブラリを使い続けることが、生産性を落とす要因になり得るということが分かります。さらに、サーバーサイドで動作するアプリケーションであれば、その動作環境のアップデートに対応させなければ、アプリケーションを動作させることすらできなくなる可能性もあるのです。

信頼性の維持・向上

システム運用業務には、ソフトウェアのデプロイ(リリース)や、システムのモニタリング、障害対応、セキュリティ対策、定期的なバックアップ、システムリソースの調整など、様々な作業が含まれます。運用担当者は、これらを日々、淡々とこなしているわけではありません。サービスレベル目標を達成するというミッションがあるからです。

ソフトウェアシステムの「信頼性の維持・向上」は、システム運用業務の主目的でしょう。これは、ユーザーに向けた「サービスレベル」の達成を通して、ユーザー体験に貢献しようとする活動です。

サービスレベルとは、プロダクトの振る舞いに求められる性能などを指標化、目標化したものです。たとえば、サーバーの応答速度やエラー率などがその指標です。「稼働率99.9%」なら、稼働率が指標で、99.9%が目標です。よく聞くSLAとは、サービスレベル目標が達成できなかった時(できた時)について顧客と取り決めた規定です。

サービスレベル目標がもたらすものは、「プロダクトの正常な状態の定義」です。この定義がなければプロダクトが正常であるかどうかの判断ができません。人によって判断がばらついてしまうと、サービスレベルを過剰に上げる努力に時間を費やすことになりかねません。目標があるからこそ、それを下回りそうである傾向を事前に検知することも、適切に対処することも可能になるのです。

トイルの削減

システム運用業務に多くの人や時間が奪われているようなら、トイルにまみれている可能性があります。トイルは次のように定義されています。

トイルとは、プロダクションサービスを動作させることに関係する作業で、手作業で繰り返し行われ、自動化することが可能であり、戦術的で長期的な価値を持たず、作業量がサービスの成長に比例するといった傾向を持つものです。

書籍『SRE サイトリライアビリティエンジニアリング』より

トイルの特徴の1つである「手作業」で繰り返すシステム運用は、エンジニアの時間を奪い、品質にバラツキを生じさせる要因となります。作業に失敗すれば、修復のため、さらに時間が奪われることにもなりかねません。

また、トイルの煩雑な作業手順を別の担当者に引き継いだり冗長化することにも手間がかかります。しかし、それを惜しむと作業が属人化してしまう。

このように、トイルはやっかいな存在であり、システム運用業務を非効率にする要因なのです。さらに、開発チームがシステム運用も担っている組織であれば、開発の生産性にも影響します。機能追加、機能改善といったソフトウェア開発業務の時間が、煩雑なシステム運用業務によって奪われることになるからです。

現場を見回すと、毎回あたり前のように手作業で行われている作業が意外と多く存在します。それが日常になってしまっていて、本人たちも気付いてないのです。こういった作業を積極的に自動化していけば、システム運用業務に多くの人、時間が奪われる状況を改善することも可能です。

それぞれの時間を計測し可視化する

ユーザー体験の維持・向上を目的とする活動だけが、組織にとって有益なエンジニアリング業務ではありません。効率性の維持・向上を目的とする活動がなければ、ユーザー体験の提供もままならなくなり得ます。ユーザーやビジネスを巻き込んで大きなトラブルを引き起こすことさえあるでしょう。

それぞれの活動のバランスをどうすべきか。それは、組織やプロダクトのステージによって異なります。いずれにしても、まずは現状を把握することが有効な手段になるでしょう。自組織がそれぞれの活動にどれぐらいの時間を割いているかを計測し、可視化するということです。

そうして計測した指標と、自組織で採用している生産性指標を組み合わせることで、取るべきアクションがきっと見えてくるはずです。

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