エンジニアは実装と戦う前に UI と戦った方が幸せになれる 〜 メンタルモデル駆動開発の TIPS 〜

## まえがき
メリークリスマス。
[LancersAdvent Calender](https://qiita.com/advent-calendar/2018/lancers) 25日目の記事です。前日は　@autumnlike([@intrudercl14](https://twitter.com/intrudercl14)) による [複雑な仕組みと向き合い、会計システムをリプレイスした話](https://qiita.com/autumnlike/items/262116fad408a35cbc7f) でした。
世にあまり出ない会計に関する内容なので、是非シェアしていただいて皆さんの元に届けば幸いです。

本記事は自分がやっていた [pook というサービスが終了](https://qiita.com/numanomanu/items/fbb2d3b35c77051349f7)してしまい、知見がリポジトリの issue にだけ残るのはもったいないので、考えていたことなどの一部を公開しようと思った次第です。

## はじめに
みなさんは、プロダクトを作っていてこのような経験はありませんか？

- 作っていざ使ってみたら使いにくかった
- 顧客が本当に必要なものはコレじゃなかった
- UI が複雑でシンプルでない結果、実装も複雑でシンプルでない

そのたびに作り直したり、仕様変更して精神をすり減らすことは、大いなる時間の無駄だと思います。ある程度企画や画面の段階からもしっかり踏み込んでいったほうが、最終的に幸せになれるのではなないでしょうか？

普段エンジニア（プログラマ）として仕事していると、どうしても実装することばかりに関心がいって、要件や UI などに関心が向かなかったりするのですが、いろいろと仕事をしていく中で、要件や UI 側はもっとエンジニアが提案していくべきだと強く思う場面が何度かあったので、知見としていくつかパターンを記録しておきたいと思い、記事にした次第です。

そもそもプログラミングと同じように ui もパターンを知らなければ、どういうふうに実装したほうが良いかもわかりにくいと思います。

なので、今回は自分が作っていた pook という c2c のスキルシェアアプリの実装や UI を元に、どういうふうに考えて作ったのか。また、それらのパターンを知見として共有したり、エンジニアとしてどういうアプローチを行ったかなどをお伝えできればと思います。（ユーザー数も少なかったのもありますが、割と複雑なシステムのくせにユーザーからの使い方に関するお問い合わせなども少なかったので、わりと上手く作れていたのではないかと推測しています）

ちなみに、手戻りしまくった結果こんな内容で登壇しました [新規事業開発におけるエンジニアの心得〜失敗事例から学ぶツクラナイ開発〜](https://engineer.blog.lancers.jp/2018/06/knowledge_of_engineers_in_new_business_development/) 特に今回はこの中でも UI 的な話にフォーカスしたお話を書きます。

## 事前知識
pook というサービスはスキルのECサイトのようなサービスです。例えば、家の掃除代行や、パーソナルトレーニングなどのスキルをユーザーが出品して、購入者は自分でそれを選んで買うことができます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/26095/33dca169-fb46-1050-2950-ded32ad6b003.png)

## pook の UI でこだわって作ったところ
さっそく、 UI の部分でこだわったところの TIPS を紹介したいと思います。

### 1. WalkThrough を入れて紙芝居のように説明事項をシンプルにする
ユーザーが最初にランディングしたときにわかりやすくしたいため、アプリのような `ウォークスルー`を用意しました。最近のユーザーは WEB もアプリも関係なくなっているようなので、ここ以外にもアプリのような見た目にするところをこだわっています。
React のプロジェクトであれば [react-swipeable-views](https://github.com/oliviertassinari/react-swipeable-views) などのライブラリを使えばスグに実装できます。
ポイントとしては、こういった新しい概念のプロダクトはLPや初回起動時などは説明が多くなってしまいがちですが、ユーザーのペースに合わせて紙芝居を用意してあげると、ストレスなく伝えることができます。

ウォークスルー|
---|
![reacord11 (2).gif](https://qiita-image-store.s3.amazonaws.com/0/26095/8f502930-4a63-955e-6064-cde4d4166d70.gif)|

今回はコンセプトと簡単な使い方を紹介するウォークスルーになっていますが、こういった紹介がない場合、
「ユーザーが想像している使い方をしてくれないんだが、もっと LP 変えたほうが良いんじゃない？」とか、「もっとべつの動線あったほうが良いじゃない？」などの、追加で開発する工数などが発生することってありますよね。


#### ポイント
- ネイティブアプリのような魅せ方をすることで、ユーザーに安心感を与える
- プロダクト側でやってほしいことをユーザーのペースでシンプルに伝えられる
- スワイプが単純に気持ち良い


### 2. 初回ユーザーの流れを磨き、ユーザーの熱量を上げる
初回ユーザーと、再訪ユーザーの体験は、同じようで全くことなります。初回ユーザーの体験を良くしなければユーザーが離脱してしまいます。特に、熱量が低いユーザーをどうやってエンゲージしていくかがサービスの肝になっていきます。

pook の場合、スキルの EC サイトなので売り手と買い手の２つのユーザー属性が存在します。明確には分けてしまわずに、どちらにも転身することが可能な仕組みとしました。(売り手と買い手の鶏卵問題において、pookでは売り手を先に集めることにして、売り手が買い手に廻る効果を期待しました。)

売り手となる人はインターネットを通してお仕事をしてお金を稼ぎたい人です。こういった人は一定数いるのと、熱量が高い傾向があります。そのため、逆に熱量が低めな買い手の方を十分ケアする必要があります。
![IMG_4026.jpg](https://qiita-image-store.s3.amazonaws.com/0/26095/c47c3291-f72a-863f-9542-85afd69296e2.jpeg)

図では、会員登録後のフローを示していますが、売り手と買い手において、買い手を選択した場合は自分が興味のあるタグを選べせてから、商品一覧ページに遷移するようにしました。
理由としては、男性なのにネイルの話が出てきたりすると、自分に関係がない話だと思ってスグに離脱してしまうからです。サイトの仕組みをシンプルにすることも必要ですが、こういった細かい部分は、少し複雑になってもこだわらないとユーザーが離れていきます。

#### ポイント
- エンゲージ（熱量）の弱い方のユーザーをフォローする仕組みを入れる
- 複雑になっても、初回体験は軸を決めてしっかり実装する


### 3. メインフローとコミュニケーションを共通化する
エンジニアがよくやってしまいがちなのは、データベースのテーブルレベルでページを分割してしまうことです。例えば、メッセージであればメッセージページ。仕事管理であれば、仕事管理ページ。などです。しかしながら、プロダクトを利用するユーザーは一つのテーブルだけでなく、複数のテーブルや状態を有機的に利用する場面が多いので、サイトのメインフローとユーザーのメンタルモデルに合わせた設計が必要になります。

pook は スキルの EC サイトなので、購入する前に相談する機能（メッセージ機能）や購入した後に実施とレビューが必要です。
EC で言うところの、購入後の発送状況などを管理したり、出品者とやりとりする機能に当たる部分が、「仕事管理ページ」というものです。pook での仕事は以下のようなライフサイクルがあります。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/26095/77a655f5-15e8-c699-6447-c94800a3c2d9.png)

UI でこだわった点は、同じページ内に仕事管理とメッセージを行う機能を入れたところです。以下が仕事のやり取りをするページです。現在のステータスと、メッセージのやり取りを見ることができます。アクションを行うとメッセージが自動的に送信される仕組みも入っており、メッセージの通知が来るので、わざわざ通知を別で送る必要もありません。

実際のメッセージページ|
---|
![pook.png](https://qiita-image-store.s3.amazonaws.com/0/26095/c28c57bd-23ba-a26c-3cb9-11aaa4d86c7c.png)|

もし、仕事管理とメッセージを分けてしまうと、誰とどの仕事の話をしていたのかがわかりにくくなってしまいます。
特に C2C のサービスであれば「仕事」よりも「誰と」というメンタルモデルで進めるので、
「まず人がいて、そこからどんな仕事をするか」という概念に切り分けました。
データベースのテーブル構造に依存してページを作るのではなく、現実世界で利用するユーザーの気持ちを考えて、ページを作りましょう。

その結果

- メッセージページの上部には仕事の次のステップとステータス（１）
- 「次やるべきことをボタン」を上部に設置することで、ユーザーが何をすればいいかを明示（２）
- メッセージ上で仕事のやり取りを行い（３）
- 予約表の発行やレビューなどのアクションを行うと、自動的にメッセージも飛ぶ


という仕組みになりました。
結果として、メインフローとユーザー間でのコミュニケーションを行うページを一緒にしたことで、

- 誰と何をしていて
- 次に何をするべきか
- 過去のやり取りの履歴と、相手へのコミュニケーション

をスムーズにすることができました。

メインフローとコミュニケーションの共通化|
---|
![pook.jpg](https://qiita-image-store.s3.amazonaws.com/0/26095/dc50d903-c1aa-1945-e994-9e21593a935a.jpeg)|


### ポイント
- テーブル構造に支配されず、メインフローとコミュニケーションのページをわける
- アクションを行うとメッセージが飛ぶ仕組みは、通知などをわざわざ送らなくて済む
- また「ふりこみしました〜」などのメッセージも送らなくて良くなるのでスムーズに仕事が進むというメリットもある
- ユーザーは常にこのページに TODO リスト（後述）からこのページに飛んでこれるので、迷うことが少ない

### 4. 通知と　TODO　リストを分ける
WEB サービスでありがちなのは、ユーザーが次にやるべきアクションを通知だけで送ってしまうということです。ユーザーは沢山の通知から、次にやるべき TODO の通知を見つけるのは難しくなりがちです。
また、そういう状況の中で実装を考えると、ユーザーが通知を遡る場合を想定して、データは消さずに全部持っておきましょうというような実装がなされて、そのあとの DB の index 管理や、パーティションなどで疲弊します。

通知はフロー情報なので、消えても良いものとし、TODOが必要な事に関する通知は、TODO リストを別ページで用意すると、結果的に考えることが減ります。

通知|
---|
![reacord11 (1).gif](https://qiita-image-store.s3.amazonaws.com/0/26095/1a47ef04-1294-3241-6f40-969c372f65d7.gif)|


TODO リスト|
---|
![reacord11.gif](https://qiita-image-store.s3.amazonaws.com/0/26095/cd29af65-61e7-852f-4b14-29d1f7adc5a7.gif)|


重要なポイントとして、TODOリストではなく「仕事一覧」というページにしなかった理由は、「終わった仕事」なども表示したくなるからです。あくまでここは TODO リストに徹することで、責務を分けました。終わった仕事（完了したタスク）など、ライフサイクルが終了したデータは表示しません。(終わった仕事は報酬ページから見ることができればよいのです。)

#### ポイント
- 通知は流れてしまいがち
- サービスを購入された後のフロー(ユーザーのTODO)は一番見やすいところで管理したい。
- サービスが購入からレビューまで完了して終了すると、タスクリストからは消えるので、たくさんやり取りしていても何をやるべきかが明確になる。


### 5. 不適切なサービスやコメントの通報機能
iOS のアプリを作るときに、ユーザーが投稿するコンテンツには不適切な内容を通報する機能が必要です。(pook は React.js で作っていましたが、ユーザーからの要望でプッシュ通知がほしいというのと、会社からの要望で、ユーザー数を増やしたいため獲得チャンネルを増やすために Cordova でアプリもリリースしました。)
報告を簡単にするために、標準のお問い合わせ機能に、ボタンを押せば報告の内容を入力できる状態をつくりました。新しく機能を追加する手間が省けるのと、ユーザーもお問い合わせと同じ UI で送信できるため、違和感がありません。
そもそもユーザーがコンテンツを投稿する際に、必須な機能なので、プロダクトを作る時に早めに考慮できてると、幸せになれそうです。

報告フローはお問い合わせにマージ|
---|
![reacord11 (3).gif](https://qiita-image-store.s3.amazonaws.com/0/26095/88b4dda0-044a-e16c-0cf3-447afc9c57fa.gif)|

#### ポイント
- 既存のお問い合わせフォームを流用
- 不適切なコメント内容を、既存お問い合わせフォームに転送するだけ
- スグにメッセージが送れるので通報もしやすい
- input への内容は画面遷移時にクエリ文字列で渡して、飛び先でクエリ文字列を input に注入するだけの、シンプルな実装で動いてます。

## その要件、その UI、 本当に必要ですか？
エンジニアにありがちな UI の設計方法とその乗り越え方を説明してきたましたが、そもそもどうやって、要件や UI の イル、イラナイを判断すれば良いのでしょうか。

プロダクトづくりにおいて、要件定義や UI の決定にはさまざまな論点があり、思い切って GO するのにためらわれたりするシチュエーションが存在します。

怠惰な私としては、できるだけ作り直しになるようなものは作りたくないです。
かといって、熟考する時間がなかった場合に取れる策をいくつかご紹介します。

1. そもそも別のサービスで試せないか or すでに同じようなのがないか？
2. ユーザーに聞いて客観的な意見をもらう
3. 簡易な実装で試す
4. ボタンだけおいて、需要があるか計測する

1.2.については、他のサービスを使ってみて学んだり、実際のユーザーに話しを聞けばそれなりの解が見いだせます。pook の場合は メルカリさんや中国の淘宝网（タオバオ：中国のメルカリ）などをとても参考にしました。特にタオバオは中国の文化事情もあり購入前に必ず値下げ交渉が発生するため、メッセージ画面に値下げできるように金額入力の UI があるという面白い仕組みで、かなり参考にしました。
3.4.は、プロダクト独自の仕組みに必要なので、以下に、実際に試した例を示します。

### 3. 簡易な実装で試す
ガチガチに作り込んで試すよりも、使われるかどうかだけ見たい場合は、簡単な実装で試して、その後しっかり作り込めば良いはずです。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/26095/8946f746-2c1e-d565-f67c-23c180957408.png)

[3分で API を作って世の中にデプロイするライブコーディング〜今日から君もスピードスターエンジニア〜](https://qiita.com/numanomanu/items/7bb6542961a2c567f05c) のような実装が役に立つこともあります。この機能は考えたその日に実装してリリースし、その後引き合いが良かったので、本格的な実装に取り組んでリリースしました（セキュリティの話はまたどこかで）

もしうまく行かなかったとしても、時間をかけずに作ったものなので、捨てるときもあっさりと捨てれます。

### 4. ボタンだけおいて、需要があるか計測する
意外と効果があったのはこれ。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/26095/8142c49a-4e2d-43e8-1c92-83c15d6737fa.png)

「お試し無料」のようなボタンだけ実装されているかのようにおいて、クリックした途端「現在開発中の機能です。」というモーダルを出します。裏ではこのクリック率を計測して、どのくらい需要があるのか。を可視化します。

**定性的な仮説が、定量的な事実へと変化するので議論しやすくなります。**おすすめです。

要件や UI が必要かどうかで迷ったら、

- 作らないで試せないかを考える
- 試したい仮設をスグに実装できないか考える

を常に考えると、後々苦労しなくて済みます。

## そもそも、エンジニアは何故コレができない？
言われて見れば、当たり前っぽい実装だけど、エンジニアだけで実装すると、ユーザーを無視した作りになりがちなのは何故？（皆さんは心当たりないですか？）

自分の一つの解は、 ~~WEB アプリを構成するための MVC フレームワークに引っ張られたり RESTful な API の思想に引っ張られたりするのが、原因なのではと想像しています。~~ (追記 2018/12/26 誤解を与える書き方ですみません。思想に引っ張られると言うより、サンプル的な実装になって、ユーザーを置き去りにしていないか。ということが言いたかったです）
rails や cake, django などのチュートリアルなどを見ても、記事のテーブルを用意して、それにコメントできるようにして。。。などのシンプルな設計のものが多いです。そのため、それらを逸脱するような設計になるとレールから外れることになるので、そもそも実装できなかったり、できたとしても複雑な設計になってしまうのではないかと邪推しています。

しかしながら、実際のプロダクトは複雑で、いろんなデータや概念を扱っています。
最近ではそれらをまとめるために BFF 層などを導入したり、フロントエンド側で正規化したデータをストアして、表示する時に必要なものを取り出す手法などが台頭したように思います。(例えば  [Redux Real World Example](https://github.com/reduxjs/redux/tree/master/examples/real-world) では、後者の正規化を利用した example が見れます。なかなかおもしろい実装です)

小難しい実装を突き詰めても良いんですが、それよりももっと前に、要件定義や UI を見直せばそもそも必要ない実装だったりもするんじゃないかなと思って、この記事を書いてみたのですが、なかなか真理にはたどり着けそうになかったです。

もう一つは、画面をそれぞれ点でとらえてしまった結果、一連の体験としてみた時に破綻しているパターンがあったりすることです。これを UX と呼ぶか迷いますが、点ではなく、線で見ることが、実装にフォーカスすると見えなくなってしまいがちです。最近やってよかったのは、モブプログラミングならぬ、モブテスティング（？）という手法です。みんなで、大きな画面を見ながら、設定したペルソナユーザーの気持ちを発話しながら、一つ一つの UI を触っていくと、違和感がある場所がかなり出てきます。実装する前にチームメンバーでやることをおすすめします。

言いたいことは、**エンジニアはユーザーのメンタルモデル*をもっと想像して物を作りましょう。（自戒の念を込めて）** ということです。

`*頭の中にある「ああなったらこうなる」といった「行動のイメージ」を表現したものである。`

## おまけ
UI について、どうやって知見を溜めるか？
- 徹底的に最近出たアプリを触り、違いを理解する
- ソシャゲやテレビゲームをする（ゲームのほうが複雑で優れたUIが多い）
- それっぽい本を読む

それっぽい本でいうと「インタフェースデザインの心理学 ―ウェブやアプリに新たな視点をもたらす100の指針」などはウェブアプリなどを作っている人にとって、読んだことない人には読む価値がある本ではないかと思います。

## 最後に
エンジニアとして仕事をしていると、ついつい実装に集中して、要件や UI を忘れがちになってしまいますが、そもそもユーザーにとって必要でない機能を作ってしまうことが一番のリスクなので、そういった事態を防ぐ、もしくは作ったとしても簡単に捨てたり、作り直したりできることが一番大事です。そのためにもユーザーのメンタルモデルを察するための仕組みや観察に労力をさける準備がもっと必要なのではないかと感じています。

- ~~MVC フレームワークなどの思想に囚われすぎた設計になり、ユーザーを置き去りにしていないか~~ 書き方悪かったです。すみません。MVC　よりも、「フレームワークのサンプル的な実装でユーザーを置き去りにしてないか」です。
- エンジニアでも UI にこだわると、手戻りが発生することが少なくなるかも
- 作らなくて済む方法をスグ試したり、定性的な判断ができる手法を引き出しに持っておくと便利
- いちばん大事なのは、ユーザーのメンタルモデルを考えてハックすること

エンジニアの仕事は「技術で問題解決することであり、プログラミングすることではない」という師の言葉があるのですが、まさにプログラムだけ書くのではなく、要件定義や UI にも入っていくことが、エンジニアとして求められるスキルなのかもしれません。

作らないという究極の怠惰のために本気を出して、いろいろ UI などの勉強をするのも悪くないのではないかと思いました。
この中のチップスが、誰かの役に立てば幸いです。