始めまして、まこっちゃんです。Qiita初投稿です。
これはアドベントカレンダーほぼ厚木の民の17日目の記事です。
はじめに
本記事の趣旨
「デザイン思考」というものを学ぶ機会があり、これは要求の定まっていないプロジェクトを進めていくのに有効な考え方だと感じました。
しかし、調べてもプロジェクトの進行がどうあるべきかという話ばかりで、企画やPMにはいいのかもしれませんが、開発チーム目線で書かれた解説は全然見つかりませんでした。
ということで、自分なりにエンジニア目線で「デザイン思考」を解釈するとどうなるかを書いていこうと思います。
内容としては、先行検討的なプロジェクトを経験してきた方々が非言語的に会得しているものも多いかと思いますが、言語化することで見えてくることもあると思いますので是非読んでみてください。
また、正解がある類の話ではないので間違っているということにはならないでしょうが、気になる点等ございましたらコメント頂けると幸いです。
対象の読者層
- デザイン思考って何やねん、な人
- よう知らんけどデザイン思考流行っとるね、な人
- デザイン思考ってエンジニアが気にすることちゃうやろ、な人
本記事で想定する状況
先行検討的なプロジェクトでざっくりとやりたいことだけ企画や上司から言い渡されて、何度も要件定義を繰り返しトライアル&エラーで開発を進めていくことになった。
開発は個人ではなくチームで行い、その進捗管理もする必要がある。
そもそもデザイン思考とは
デザイン思考とは、顧客を観察・分析し、試行錯誤を繰り返して、顧客価値に繋がるものを生み出そうというマインドのことです。
ちなみに、似た言葉に「人間中心設計」や「サービスデザイン」という言葉がありますが、それぞれ下記のような意味です。
・人間中心設計(HCD)
デザイン思考に基づいて設計・開発を進める際に推奨されるプロセス
・サービスデザイン
人間中心設計に基づくプロジェクト進行をする上での具体的なフレームワーク群
いずれにせよ、**「サービスや商品は顧客の困りごとを解決するものや要望を叶えるもの」**という考え方が元になっています。
これは現代では主流の考え方(クリステンセン先生のJob理論辺りからでしょうか。)なので特に異論はないでしょうが、非常に重要なのでよく意識するようにしてみてください。
デザイン思考で大事なこと
デザイン思考を学んでみて大事だと感じた点を3つに絞りましたので紹介します。
1.アイデアより着眼点
どう解決するかというアイデアではなく何を解決するかという着眼点に重きを置きます。これはシュムペーターの『イノベーションは新結合である。』と同様の考え方ですね。
筆者もそうですが、エンジニアはどうしても新規性の強い技術に注目しがちだと思います。しかし、真に顧客価値の高いサービスは、奇抜でハイテクノロジーかどうかは関係なく、自分の課題を解決してくれるものですよね。(その実現に高い技術力が必要になることは当然あり得ます。)
プロジェクトの進め方に迷ったら、「何を解決したかったんだっけ」と立ち返るようにしてください。
2.ユースケースを具体的に想定
解決しようと定義する課題は、具体的なユースケースに紐づいているべきです。
プロジェクトを立ち上げた時点では、漠然と「こういうことが出来たらいいよね」で始まるかと思いますが、本格的に開発に入る前に、誰が、どういう状況で、何のために使うものなのかを想定し、企画やマネージャと摺り合わせておくと開発してからの手戻りが減ってみんなが幸せになれると思います。
開発していく1サービスで複数のユースケースを想定できることも多いかと思います。その場合は、それらをサポートする(機能実装の)優先順位も合わせて摺り合わせておくと後段が楽になります。
3.課題設定は何度も行う
解決しようと定義した課題が正しく顧客価値を生むのかは、顧客も含め、誰も知らないのです。
そのため、議論したりプロトタイプを作って使ってみたりして再定義を繰り返すという工程がどうしても発生します。
一旦決めた仕様でシステムを完成させても、「いやーなんか違うな、ここをこう変えてみようか。」となることが普通だということです。「この間は『これでいいよ。』言うたやんか。何で意見変えとんねん。」という気持ちは抑えて、「これでは上手くいかないことが分かっただけ前進したな。」と考えていきましょう。
また、このサービスが何を解決するのかを決めるのは上の仕事という考えも捨てましょう。開発側も一体となってサービスを作り上げていくのが理想です。
では実際の開発工程はどうなる
いよいよ本題です。
ここでは「サービスブループリント」というサービスデザイン手法(デザイン思考との関係は上述)のうちの1つをベースに、デザイン思考に基づく開発工程を考えてみたいと思います。
例があった方が分かりやすいと思うので、以下では食事管理サービスの開発を例に用いて説明を進めていきます。
プロジェクトの方向性を摺り合わせよう
「食事管理サービスの開発をしてくれ。」と指示されたとします。
その指示を出してきた側にも具体的なターゲットの想定が何かしらあるはずなので、まずはそれを聞き出しましょう。
例えば、「日々の健康を気にする人をメインターゲットに」「栄養管理をする」「スマホアプリ」を作ってほしいという話になったとします。
この時点で合意が取れていなければしっかり煮詰めましょう。実現可能性が低いと感じた場合も実装イメージを話し合ってみて、ターゲットを修正したり、別の実装方法に落ちつけたりしましょう。
また、ターゲットが広いと感じた場合は、"Extream users"に注目して絞り込むとよいとされています。どういうことかと言うと、そのサービスが解決しようとしている課題に最も危機感を抱いている人をターゲットとするということです。この場合では、例えばアレルギー持ちの方かもしれませんし、糖質制限をするボディビルダにしようという話になるかもしれません。ここで培ったノウハウは"Normal users"にも適用可能であるという思想です。
折角ですので、ここでは「アレルギー持ちの小学生のお子さん2人を持つ親御さん向けの栄養管理アプリ」を開発することになったとします。
(アレルギー持ちの小学生のお子さん2人を持つ親御さん、などの具体的な人物像を「ペルソナ」と呼び、デザイン思考では非常に重視しています。ここまで会話出来ていると非常に手戻りを低減できるように感じます。)
要求分析をしよう
では、対象のペルソナは具体的にどんな課題を抱えているのでしょうか。このサービスを使ってユーザは何が出来たら嬉しいでしょうか。
一般に、これを考察する工程を要求分析と呼びます。
要求分析過程で重要になるのは時系列的にユーザ体験を想定することです。ユーザストーリと言ったりもします。
今回の例であれば、例えば次のようになります。
- 子供たちから○○を食べたいと言われる…そう言えば最近○○食べてなかったね。折角だし○○を食べさせてあげたいな。
- 献立を決める…○○をメインにして、栄養バランス考えて、アレルギーは避けて、って考えると□□にしようか。
- 買出しに行く…今日、スーパーが特売だったっけ。車で行こうっと。
- 料理する…子供たちが17:30くらいに食べたいだろうからそろそろ作り始めなきゃ。
- 家族で食べる…子供たちが喜んでくれた、嬉しい!
- 片づけをする…ちょっと残っちゃった、明日に取っておこうかな。
この時、ペルソナ目線での課題に気付くために、その時の感情を想像して書き出すとよいとされています。
例えばここで、2.3.に注目してサービスを考えてみましょう。
そして、「食べたいものとアレルギーを入力すると献立をサジェストしてくれ、その買い出しのおすすめお店情報を見れる」みたいなものを作ろうと決まったとします。
この時点である程度要素分解しておくと後段が楽になります。
要件定義をしよう
作りたいものが決まったら、今度は機能としては何があれば良いかをリストアップします。
この工程を一般に要件定義と呼びます。
この時、要求のどの要素を満たすための機能なのかを紐付けて洗い出すと漏れなく実施出来るかと思います。
入力機能ー食べたいものの入力
∟アレルギーの入力
献立のサジェストー献立立案
∟献立とレシピの表示
∟別の献立を見る
︙
の様に洗い出して行きます。
また、こういう機能があっても便利かもしれないと思いつくこともあるかもしれません。
例えば、「アレルギーの入力は保存出来る様にしよう」、「ユーザの位置情報を元に近くのセール情報を取り込もう」などといったものです。
そういった場合は恐れずに要求分析に戻りましょう。
そして改めて優先順位を議論し、採用しなかった方はバックログとして保存しておきましょう。
余談ではありますが、この時点で各機能の評価方法や評価基準を決めておくと認識ずれをかなり抑えることが出来ます。これをテストファーストの理念(実際にはもっと深い概念なので気になる方はご自分で調べてください。)と呼んでいます。
仕様策定をしよう
さて、ここまで来るといよいよ本格的な設計になってきます。要件定義で洗い出した実装すべき機能をどのように実装するかを決めていきます。UMLなどを駆使して完成物がどういう構成になるかをチームで摺り合わせるとよいでしょう。
この工程を一般に仕様策定と呼びます。
この時、特に意識せずともそうする方は多いかもしれませんが、**「オブジェクト指向」かつ「イベント駆動」**での設計としておくとよいです。
というのも、オブジェクト指向ではどこがどの機能を担っているのか明確なので仕様修正時にどこを修正すればよいかすぐに理解できますし、イベント駆動で組んでおくと仕様に修正が入った場合にsubscribeするしないを変更するだけで済みます。
これがシーケンス型で書かれていると修正箇所の影響範囲がぱっと分からず、関係のないところまで変更が必要になったりします。
また仕様を検討する内に、要件定義で実装することに決めた機能の中で制約条件が付いてしまいそうな部分が出てくるかと思います。
例えば、「食べたいものの入力は1個のみとする。」などです。
この点に関しては、特に用心深く、チームで話し合うとよいでしょう。
そして、制約条件を認めることになった場合は、形式は問いませんがそれらをどこかに記載して管理することをおすすめします。
実装を進めていこう
一般に知られている開発手順に「ウォーターフォール型」「アジャイル型」「プロトタイピング」「スパイラル型」の4つがありますが、それぞれの特徴を纏めておきます。
・ウォーターフォール型
要求分析→要件定義→仕様策定→実装と順番に進めて行き、前の工程には戻らない。仕様変更が想定されない様なプロジェクトで進捗管理をスムースに行うための手法。
・アジャイル型
1機能毎に完成させていき、試運転しながら次に実装する機能を改めて議論しながら進める。要件が変わりうるプロジェクトで進捗を可視化するための手法。
・プロトタイピング
実装予定の機能をモックアップレベルから擦り合わせし、徐々に質を上げていく。要件はほぼ確定しているが仕様が纏まらないプロジェクトで手戻りを減らすための手法。
・スパイラル型
アジャイル型とプロトタイピングのハイブリッド。機能数と質を徐々に上げながら仕上げていく。要件が変わりうるプロジェクトで手戻りを減らすための手法。
今回の様に要求を探りながら進めていくタイプのプロジェクトではアジャイル型やスパイラル型が有効ですが、現実的には進捗管理を求められることがほとんどかと思いますので、「この機能とこの機能までは実装出来ましたので、この使い方なら動かせます。」と説明がつくアジャイル型がおすすめです。
アジャイル型が流行っているのはそういう理由なんだと思います。
PoCを何度も実施して試運転しながら要求や要件を見直していくことになりますが、どのPoCまでにどの機能を実装して、どういうシナリオを試すのか、と話し合いながら実装スケジュールを引くとよいでしょう。
実装が終わったら
要件定義のフェーズで策定した評価方法と基準を元に、正しく実装出来たかを確認します。
一般に、この工程はテストや評価と呼ばれますが、所謂品質保証(QA)とは別の工程です
ここで見つかったバグは、実装ミスまたは仕様の不具合のいづれかだと思いますが、後者の場合はもう一度仕様策定からやり直し、必要があれば要件も修正します。
また、実装した機能が顧客価値を満たすのかを検証するためにPoCも実施します。PoCではユースケースに紐づいたシナリオを設定し、それを意識して実施することが望まれます。
ここでの結果を基に、要求を修正し、また、各機能の実装の優先順位を見直します。
これを繰り返して満足のいくサービスを作り上げていくのですが、一点注意しなくてはならないのが、次の機能実装に移る前に必ずリファクタリングを行うべきであるということです。
上述で確認した通り、機能コンポーネント単位で設計していくことになりますので、各機能コンポーネントは綺麗に整理されている必要があります。
特に、短いプロジェクトなら汚いままでも乗り切れますが、要求がなかなか煮詰まらないことも多く、その場合はリファクタリングを挟まない方が余計に時間を取られることになりえます。
リファクタリングを甘く見ず、しっかりスケジュールに組み込むようにしましょう。
--
本記事は以上になります。
最後まで読んでくださってありがとうございました。
皆様、よいお年を。
参考文献
https://note.com/goofygoof/n/n084cd763f27f
https://ux-jump.com/hcd-designthinking
https://www.concentinc.jp/design_research/2011/12/service-design/
https://goodpatch.com/blog/serviceblueprint-for-renewal/
https://blog.btrax.com/jp/design-thinking-difference/
https://note.com/nakanoyutaka/n/n2f35a1a01534
https://note.com/goofygoof/n/n562b8e2abb5f