Tryswift rachel bobbins cover

Swift版「誰のためのデザイン?」

ドン・ノーマン著「誰のためのデザイン?」は身の回りの道具のデザインにフォーカスした、デザインの分野の古典です。そこに記されている原則の多くは物理的なモノ以外に対しても当てはまります。例えばSwiftにもです!try! Swiftで話されたこの講演で、Rachel Bobbinsが整然とした、読みやすいSwiftのコードを書く���めには、その本に記されている原則を、コードを書くときにどのように適用すればいいのかを解説します。


ドン・ノーマン著「誰のためのデザイン?」 (0:00)

私はRachel Bobbinsと言います。サンフランシスコのStitch Fixで働くiOSエンジニアです。

数か月前、休暇を利用してドン・ノーマンの「誰のためのデザイン?」を読み直すことにしました。この本は、すばらしい体験のアプリケーションを作るにはどうすればいいかということについて非常に参考になります。簡単にいうと、ユーザーファーストによるものづくりをするために、デザイン、心理学、認知科学の考え方を組み合わせていく、というものです。

初版ではこの本は物理的なモノについて書かれていました。最近の改訂では、デジタルのインターフェースデザインについても触れられています。休暇中にコードについて考えたくなかったので、この本を読み返すことにしました。残念ながら、本を読んでいるといつも、本に書いてある概念と、自分のiOSデベロッパーとしての仕事の内容を結びつけてしまっていました。

Swift版「誰のためのデザイン?」 (2:15)

この本から学ぶことがあると、iOSデベロッパーとして感じていました。私たちはいつも、ユーザーに対して正しいことをするにはどうすればいいのか考えています。自分のアプリやコードによってユーザーに喜んでほしいと思っています。みなさんは優秀な技術者ですから、もっと読みやすくて、キレイで、理解しやすく、かつ、採用しやすいコードを書こうと心がけていると思います。

それを実現する方法として、新しい概念を紹介します。デザイン思考というこの概念を用いて、どうすれば構造化されたコードを書けるのかということを、よりクリエイティブに考えます。そして、クリーンで読みやすく、テストしやすいコードを書くという目的を達成することができるでしょう。

ユーザー (3:39)

ユーザーとは誰でしょうか?この本はユーザーにフォーカスしたデザイン原則を提唱したことで知られています。けれども、もし私たちがユーザーにフォーカスするなら、ここでいうユーザーとは誰のことなのか、共通の認識を持たなければなりません。

デベロッパーとしてユーザーというと、私はこのように考えます。

  • App Storeから私たちのアプリをダウンロードして、使っている人たち。
  • 企業向けのアプリを開発しているなら、ユーザーは必ずしもアプリをダウンロードする必要はありません。そして、仕事で使う必要があるので使っているという人たちです。どちらのユーザーも私たちが作ったアプリのインターフェースを通じて、アプリを使います。しかし、この講演の目的としては、いま挙げた人たちはユーザーとは定義しません。
  • Swiftデベロッパーをユーザーと考えると、ユーザーは私たちと同じで、アプリを使うこともあるでしょうが、自分でコードを書くこともあります。おそらく、別のチームのデベロッパーたちですね。彼らは将来的に同じチームなるかもしれません。ですので、アプリをダウンロードして使ってくれるユーザーに対する場合と同じように、この人たちを大切に考えなければなりません。同じコードベースでやり取りをする人たちに対しても、同様に良いユーザー体験を提供していきたいです。そうすると、App Storeからアプリをダウンロードして使っているユーザー、とは少し異なった目標や、考えるべきことがあります。

やってみましょう (5:03)

それでは、ここで本に載っているちょっとした心理学のレッスンを紹介します。(プログラミングのレッスンのように見えますが、だまされないでください)。

記事の更新情報を受け取る

簡単なiOSアプリケーションを作ろうとしています。ビューコントローラが1つあるだけで動きはありません。ただ英語と日本語の両方で 「ようこそ」 と表示するだけです。

まずはじめに、完成形を定義しましょう。このアプリには2行のテキストが必要です。1行めが英語で、2行めが日本語です。テキストは画面の縦からも横からもちょうど真ん中に表示することにします。画面が回転したり、サイズの異なるデバイスで実行したとしても正しく表示されるように、Auto Layoutを使用します。

もう少し具体的にしていきましょう。Auto Layoutはコードで設定することにします。iOS 9から使えるようになった、NSLayoutAnchorを使いたいからです。ローカライズも必要です。

完成形を頭の中に思い浮かべて、実���方法を考えます。もうお分かりですね。(およそ20行ほどの)小さなビューコントローラを書きます。そして Play ボタンを押せばアプリがビルドされて、期待した通りに実行されるでしょう。

しかし、間違いがあったようです。コンソールに警告が表示されています。警告の内容を解釈して、そこから何が起こっているのかを読み取ります。これまでの経験やアプリケーションの状態と照らし合わせて考えます。最初に考えた目標が達成できていないので、新しい目標を設定します。新しい目標は、この未完成のコードを正しく直すことです。最初から書き直してはいけません。

新しい目標を達成するために、Xcodeに戻りましょう。直し方はすでに頭の中にあります。デフォルト値がtrueにセットされている行をfalseにセットします。アプリを再ビルドして実行します。アプリは期待した通りに正しく動いています。問題は解決しました。

行為の7段階理論 (8:18)

この例を通じて「誰のためのデザイン?」の本による 「行為の7段階理論」 というものを見てきました。 それは、

  1. ゴールの形成 (Goal)
  2. 意図の形成 (Plan)
  3. 行為の詳細化 (Specify)
  4. 行為の実行 (Perform)
  5. 外界の状況の知覚 (Perceive)
  6. 外界の状況の解釈 (Interpret)
  7. 結果の評価 (Compare)

というものです。 実際にはこのステップを2回繰り返しました。最初は意図的に分かりやすく説明しながらそれぞれのステップを実行しました。2回目はデバッグの最中にサッと(ほとんど無意識のうちに)実行しました。

この7段階のステップをデベロッパーは無意識のうちに1日に何度も行っています。しかし、自分のコードを別のデベロッパーが将来的に見るようになったときのために、この7段階のステップをわかるようにしておきたいです。7段階のステップを残しておくことで、謎めいたコードがデバッグしやすくなったり、トリッキーなバグを究明しやすくなったり、新しい機能を追加しやすくなったりします。

デザインの7つの原則 (9:26)

外界の情報と内部の知識の両方を利用する 作業の構造を単純化する 対象を可視化し、実行と評価におけるへだたりを埋めるようにする 正しい(=自然な?)対応づけがなされるようにする 自然の制約や人工的な制約などの制約の力を活用する エラーを前提とし、それに備える 以上のすべてがうまくいかないときには、標準化を行う

「誰のためのデザイン?」の中で、ノーマンは「行為の7段階理論」の各段階に対応した「デザインの7つの原則」も述べています。

  1. 発見しやすさ (Discoverability)
  2. フィードバック (Feedback)
  3. 概念モデル (Conceptual model)
  4. アフォーダンス (Affordances)
  5. シグニファイア (Signifiers)
  6. 対応づけ (Mappings)
  7. 制約 (Constraints)

この原則はコードをキレイに、読みやすくするときに使えます。子の原則はそれぞれ相互に排他的ではなく、それぞれに相互作用しています。例えば、フィードバックを返すということは、ユーザーのシステムに対する概念モデルに影響を与えます。一方で、表現やシグニファイアが欠けていると、このコードベースでできることを見つけてもらえないかもしれません。

コードを書くときには、他の人とうまくやり取りをするために、この7つの原則を意識するといいでしょう。

「誰のためのデザイン?」の中で、ノーマンは物理的なモノを例に挙げて(ティーポット、ドア、電気のスイッチなど)説明しています。私も自分のアプリのインターフェースで使われている、何らかの物理的なモノを用いて説明しようと思います。また、このインターフェースに対する考え方を、コードとプログラミングに適用する方法を説明します。

発見しやすさ (10:15)

「設定」アプリの「画面表示と明るさ」を見ると、そこで何ができるのか、直感的に分かります。画面を見て、画面の明るさと文字の大きさを変えることができると分かります。

このアクションは 発見可能 でした。何ができるか理解するのに、考える必要はありません。

ここで、先ほど作ったアプリを考えます。このアプリには「発見しやすさ」に少し難があります。 実行する前にあるフラグをfalseにセットしなければいけないことが分かりませんでした。これを必須の設定にする必要があることが分かります

ユーザーである現在または将来におけるこのアプリのデベロッパーに対して、システムにこのようなプロパティがあることは重要になります。そのため、現在のデベロッパーは、コードベースでこのような重要なプロパティを使っていることを発見可能にしておかなければなりません。

Swiftでは重要な部分を発見可能にしておくための、方法はいくつかあります。

  • メソッドやプロパティをpublicprivateまたはinternalを指定します。他の人に何を発見可能にして、何を発見できないようにするかを示すことができます。
  • テストを書きます。テストを読めば、どのようにオブジェクト同士が作用し、期待する振る舞いは何なのかが分かります。テストが無ければ、重要なプロパティがありそうな部分のコードを深く追いかけて理解する必要があります。すぐ理解できる人もいるでしょうが、そうではない人もいます。
  • メソッド名や変数名を賢く付けます。特に補完が直感的に働くようにします。UITableViewのデリゲートとデータソースには合わせて30個以上のメソッドがありますが、そのうちの2つのメソッド名は「tableView」から始まっていません。2つ以上のセクションを持つテーブルビューを作るとき、私はいつも自動補完のウインドウをスクロールして出てこないことにイライラしています。
  • コメントとドキュメントがあると、重要だが明らかではないプロパティを見つけやすくなります。例えば、ワークアラウンドの説明としてStackOverflowのリンクを載せておいたり、ビルドシステムにトリッキーな依存関係があるならコメントに書いておきます。これはコードの一部ではありますが、それは明らかではありません。直接はコードに関係がないからです。しかしコメントやドキュメントに残しておけば、見つけてもらえる可能性は高くなります。

フィードバック (13:57)

「言語と地域」の設定を自分のiPhoneで開き、言語を英語から日本語に切り替えようとしたとします。そうするとアラートが表示されて、本当に変更していいか確認します。日本語ができないユーザーである私にとっては、これは非常にありがたい振る舞いです。アラートのおかげで、間違えて言語を切り替えてしまうことを防げます。これはiPhoneがタップしたという行為に対して、適切に応答しているので、良いフィードバックといえます。

フィードバックはユーザーのアクションが成功したか失敗したかどうかの情報を示します。同様に、コードベース上でやり取りがあるデベロッパーに対して、できるだけ多くのフィードバックを返そうとするべきでしょう。 ポジティブフィードバック は問題が起こってないことを示します。 ネガティブフィードバック は何か問題が起こっていることを示します。最も良くないフィードバックとは フィードバックが無いこと です。デベロッパーは自分の考えが正しいかどうかを常に確認しなければならないからです。

デベロッパーであるからには、コードベースにおいて 自動化されたフィードバック を返すように努力しましょう。

  • コンパイルエラーと警告。即座にXcodeに赤いマークが表示されるので、何かが間違っていることが分かります。デベロッパーに問題に対処することを強いることができます。
  • 失敗するテスト。テストがすべて通ったら、それは何も壊さず、期待した通りに正しく動いていることが分かります。テストが失敗しているなら、それは何かが壊れていることを示しています。ネガティブフィードバックの例です。
  • 実行時にクラッシュしてしまうことは、あまり有用なフィードバックとは言えません。クラッシュを再現するために、どういう状態だったか、どういう手順だったかを思い出す必要があります。実行時のクラッシュはただ何か特定の手順でそれが起こるということだけが分かります。

さらに、 人の手によるフィードバック を使うこともできます。例えばペアプログラミングやコードレビュー、バグレポート、App Storeのレビューもそうです。ペアプログラミングはとても優れたフィードバックの方法ですが、人類はタイムマシンを持っていないので、将来のユーザー(デベロッパー)に対してはペアプログラミングをすることができません。

概念モデル (16:52)

概念モデルの説明の中で一番気に入ってるのは、2007年にスティーブ・ジョブズがiPhoneを紹介したときのものです。そのときはスマートフォンという言葉は知られてはいませんでした。しかし、スティーブ・ジョブズはiPhoneを誰もが知っているものを使って説明しました。

彼はこれから皆さんに3つの新しいデバイスをお見せします、と言いました。広い画面のiPod、携帯電話、そしてジョブズは続けて「インターネット通信デバイス」と説明しました。ジョブズはその3つの言葉を何度も繰り返し言いました。そして最後にこう聞きました。「 もう全部持っているって?いや一個のデバイスにまとまってるんだ

概念モデルとは、すでに知っていることを用いて新しい概念を説明します。よくあることですが、デベロッパーはコードを論理的にしか考えません。( この関数は動作していて、正しい値を返している )別のデベロッパーが将来的にこのコードベースに関わることを考えると、システムがどのように動作するのかという概念モデルを作って、伝えていくようにするべきでしょう。

概念モデルは、フィードバックやシグニファイア、発見しやすさによって自分でコントロールできる部分もありますが、そうではない部分もあります。例えばその人の生い立ちや、旅行の経験、文化的背景などに概念モデルは影響されます。

アフォーダンス (19:12)

アフォーダンスはユーザーと対象物との関係性です。モノに対して私たちは何かアクションをします。 「画面表示と明るさ」の設定画面では、画面をより見やすくするための変更を加えることができます 。ドン・ノーマンは1980年の版ではアフォーダンスについてかなり強調して書いていましたが、2013年の改訂版ではあまり強調されなくなりました。デジタルインターフェースにおけるアフォーダンスは物理的なモノよりも少なくなるためです。

しかし、デベロッパーに対してはアフォーダンスはまだまだ有用であると考えています。例えば、メソッドを 呼べるようにする 。変数を 読み書きできるようにする 。変数を var として宣言することは リセット可能にする ということを示します。

将来のデベロッパーに対しては、コードが何を可能にして、アクションは何ができるのかを示すことが大切です。例えば、変数をリセットできなくしたいのであれば、それがわかるようにアフォーダンスを提供するべきです。つまり変数を let として宣言します。

シグニファイア (20:33)

シグニファイアは何ができたのか、はっきりと見てわかるサインです。「画面表示と明るさ」の設定画面にあるスライダーは少なくとも3つのシグニファイアがあります。1) 2つのアイコン、それぞれの端に配置されていて最小と最大を示しています、2) スライダー、このスライダーは離散的な値ではなく、連続的な値をとるように見えます。3) スライダーの現在の位置、現在の明るさの相対的な値を示しています。

Swiftはシグニファイアでいっぱいです。シグニファイアを用いることはコードベースの将来のデベロッパーに対して、メッセージを送るようなものです。publicprivateそしてinternal修飾子は明らかにシグニファイアです。使っても構わないメソッドとそうでないものを示しています。それ以外のシグニファイアはそれほど明確ではありませんが説明します。

データ構造を考えるとき、enumstructそしてclassがあります。enumは値をグループ化し、それぞれの値はだいたい同じ種類のものであることを示すシグニファイアです。structは値としてどこにでもコピーして受け渡して大丈夫であるということを示しています。クラスはリファレンスとして受け渡されることを示しています。実際にリファンレンスで渡されます。それはとても重要なことです。もしその振る舞いが重要でないなら、データ構造としてclassを採用することは間違っている可能性がありますね。

すべての決断とすべてのコードは何らかのサインを将来のデベロッパーに対して送っています。正しいサインを送るために絶え間ない努力をしていかなければなりません。

対応づけ (22:49)

対応づけはコントロールとアクション間の空間と時間における関係性です。私の会社のiOSアプリには、「支払いを続ける」というボタンがあります。このボタンには右向きの矢印があります。右向きの矢印は時間が「進む」ということを示すのに役立っています(少なくとも西洋の人間にとっては)。さらに根底の考えとしては次に起こることは「正しい (Right)」という意味を含めています。

このような対応づけは、文化よって異なることに気をつけてください。コントロールを空間上にレイアウトしようとするとき、そのときの対応づけが何を意味するのかを注意深く考える必要があります。

例えば、.xcodeprojファイルを整理する場合がありますよね。関連のあるファイルごとにグループ化したりしますが、そうすることによって、それを見た人はある程度のことがそこから理解できるわけです。対応づけが他の人でも理解できるのかどうかがとても重要です。

制約 (23:51)

制約とは、アクションを導くことと、制限することです。例えば、現実の世界ではハサミはそれをどう使ったらいいかを自然な制約によって示しています。私たちは導かれるように親指を穴に通し、残りの指をもう一方の穴に通します。ハサミの使い方はこうする以外にはありません。

Swiftにおける制約を説明する一番いい例は、 型システム です。型に逆らおうとしてもコンパイルエラーが起こります(これはネガティブフィードバックを即座に受ける例ですね)。型システムは、どのメソッドを呼び出すことができるのか、パラメータの型は何かの情報を持っています。Swiftの型システムはObjective-Cのときは可能だった間違いを許容しないように作られています。

まとめ (24:52)

まとめますと、デベロッパーはキレイで、読みやすく、保守しやすいコードを書こうと心がけています。ですが、そのことを成し遂げるためのエンジニアリングを他のデベロッパーに任せてしまうことがよくあります。デザイン思考を取り入れることは、コードを書くということについて、新たな見方を教えてくれるでしょう。

デザインの理論にはあまり興味がないかもしれません。もしくは、もっと情熱を持っている分野があるのかもしれません。何でもいいです。必ずそこには哲学や原則、概念や、そういった情熱といったものをがあります。それをソフトウェアエンジニアリングに反映させることができます。他の分野からの経験やアイデアを開発のプロセスに活かすことによって、もっとクリエイティブですばらしいデベロッパーになれることでしょう。

About the content

2017年3月のtry! Swift Tokyoの講演です。映像はRealmによって撮影・録音され、主催者の許可を得て公開しています。

Rachel Bobbins

Rachel is a lead engineer at Stitch Fix, where she works primarily on their recently-released iOS app. Previously she worked on a variety of iOS and Rails project at Pivotal Labs. She’s passionate about writing well-tested code and keeping her view controllers under 200 lines.

4 design patterns for a RESTless mobile integration »

close