デザインパターン (design pattern) とは、過去のデザイナーたちが見つけた経験則的な型に対して名前をつけ、型の再利用性を高めやすくしたものです。ソフトウェアデザインの世界(特に、プログラミングの領域)においてはプログラム構造の設計パターンのことをまさに “デザインパターン” を呼び、これを共通の知識として積極的に取り入れています。

これに対しアンチパターン (anti-pattern) とは、必然的に否定的な結果に至る型を指します。アンチパターンもデザインパターンの一種と捉えこれを知識に蓄えておけば、設計の過程でどのような結果に至るのかを事前に予測することができるし、失敗を未然に防ぐことも可能となります。

今回は、アプリケーションデザインにおける典型的なアンチパターンをいくつか紹介します。

アプリケーションデザインの定義

ここでの「アプリケーションデザイン」の言葉は、以下の意味合いで使用します。
iOSやAndroidのネイティブアプリケーションにおけるデザインと捉えてくだされば結構です。

  • 主にモバイルプラットフォーム(iOS, Android)のネイティブアプリケーションの設計全般を含む
  • Webアプリケーション、クロスプラットフォーム系、ガワネイティブ系技術は含まない
  • そのほかのプラットフォームにおけるアプリケーションは含まない

パターンの位置付け

私たちはデザインに取り組む姿勢を「守破離の精神」に当てはめて考えます。

守破離(シュハリ)とは日本古来から伝わる修行の過程を説いた精神論で、まず守に徹し基本を完全に身につけ、守を極めたら破に挑戦し独自性を確立、そして最終には完全独自の流派を立てる離に到達するというものです。基本の守がなっていない者が型破りに挑戦しても、結局それは “型無し” となってしまうものなのです。

デザインパターンというのは過去の熟練者や修行者たちが編み出した型なので、これに則っておけば基本は間違いないわけです。例えばアプリケーションのUIを考えるにあたり、プラットフォームが規定する基本的なUIの構造を踏襲せずに「独自の表現をするUI」というものをいきなり盛り込んでしまうと、まるで型無しのようなとんでもないものが出来上がってしまいます。

基本を踏襲し守を固め、分かった上でそこから敢えての逸脱「型破り」を少しだけ盛り込んで独自性を出すくらいのデザインが実はちょうど良いのだろうと思います。ですから、守りを完全にものにするためのパターンおよびアンチパターンの把握はとても大切なのです。

関連:UIデザインと守破離の精神

アプリケーション内にメディア配信機能を安易に取り込んでしまう

プラットフォーム化を目指したいサービスやアプリケーションの設計でよくあるのが、関連するニュース情報の配信機能とそのUIをアプリケーション内に組み込むような発想です。例えば唐突にニュースタブが設けられて、ユーザーはそこで最新の情報に触れられるというものです。

サービスの利用時間・滞在時間を増やす施策として一見これは良さそうと思いがちなのですが、一般的なユーザーの心情としては、よほどの愛着やそこに依存する理由がない限り、いちいちあなたのアプリケーション内でニュースを閲覧したいとは強く思わないでしょう。

設計の目安

メディア配信する中身が公開Webコンテンツであるならば、素直にWebブラウザで閲覧できる仕組みにしてしまい、アプリケーションからは切り離しておく形が良いでしょう。(依存性を下げましょう)
メディアといえど、そのリーダー/ビューアのためのUI設計では細かなインタラクションまで配慮する必要があります。取って付けたようなUIにするのではなく、メディアの閲覧に適したUIを設計することが大切です。大抵はメディア配信機能はおまけ的位置付けになりがちですから、そこまでこだわってビューアのUIを設計・実装するコストは割けないかもしれません。

WebViewを使って簡易的なビューアをアプリケーションに組み込み、Deep linkを使って標準のWebブラウザにも任意で遷移できる仕組みを検討しましょう。iOSならばSFSafariViewControllerを活用して廉価的なSafariをアプリケーションに直接組み込むことも検討できます。

そしてそもそものことですが、あなたのアプリケーションやサービスにとって本当にメディア配信が必要なのかどうかをよく吟味して、それがないと成り立たないならば組み込む、そうでないならいっそのこと排除する判断をしてみるのが良いでしょう。

天気予報や時計などの機能を再発明してしまう

天気予報

サービス設計の段階でサービス事業者視点のコンセプトを描くにあたり、ユーザーがそのサービスのヘビーユーザーで、それを中心に生活している様子をどうしても思い描いてしまいます。ですが実際にはそうなるとは限りませんし、その可能性は低い前提で物事を考えた方が冷静になれます。

このことはUI設計でも気をつけなければなりません。
例えば「ユーザーが毎日使うアプリだから、天気予報の機能をホーム画面に組み込もう」といった妙なアイディアが生じることがあります。ですが、ユーザーにとって本当に天気予報が必要なのかを冷静に判断する必要があります。

設計の目安

  • ユーザーは、あなたのサービス/アプリケーションのユーザーである前に、スマートフォンのユーザーである
  • スマートフォンにはすでに時計機能や天気予報を配信する専用アプリケーションが組み込まれており、多くの人が既にそれを使っている可能性が高い
  • 日常生活の中で天気予報に触れる機会は多い
  • 天気予報は、このサービスにとって必然なのか(それがないと成り立たないのか)

iOSやAndroidには標準の時計や天気予報アプリケーションが存在していますし、ウィジェットなどのOSの仕組みを活用すればユーザーはいつでも簡単にそれらに触れられます。スマートフォン外の生活空間でも時計や天気情報はよく見られますから、これ以上天気情報を配信してもあまり意味がないかもしれません。

そのほかのコンテンツ設計でも、それがユーザーにとって必然であるのかを冷静に考え直してみましょう。

グッドパッチの受付端末

例外としては、あなたのアプリケーションをiPadなどのタブレットに組み込み、キオスクモード(特定アプリケーションのみが専用稼働できるモード。オフィスの受付や飲食店の注文端末などで利用される)で稼働させるユースケースではこの限りではありません。キオスクモードでは天気や時計、その他OS標準機能の利用が制限される上、「iPadらしさ」とか「iOSらしさ」みたいな思想はそこまで求められませんし、一般のアプリケーションよりも独自の世界観表現と「サービスや機能の再発明」は許容される可能性があります。

独自のランチャ的ホーム画面を作ってしまう(スーパーアプリの典型)

アプリケーション設計の過程で機能やサービスが盛り盛りになってくると、それらへのショートカットを集約したいわゆる「ランチャ」UIが検討されます。ランチャがホーム画面的なUIに設置されてしまうといよいよ末期症状です。極力避けるようにしましょう。

iPhone Home

なぜなら、iOSやAndroidには立派な「ホーム」が存在しているし、アプリケーションランチャ機能もそこに備わっています。ユーザは既にそこからあなたのアプリケーションを起動してきているわけですから、ホームの先にまた第二のホームがあるような展開は望まないでしょう。このようなホーム内ホーム、二重のランチャの仕組みはただ使い勝手が悪いので、アプリケーションの外側のユーザーの使い方を踏まえた適切な設計を目指すのが望ましいでしょう。

設計の目安

  • ランチャ機能を作りたくなったら、一旦踏みとどまる
  • ランチャではないナビゲーションの仕組みを検討する
  • 「ホーム」という命名から設計を見直してみる(「家」のメタファである必要があるかなど)
  • 多くのサービスを一つのアプリケーションに組み込むと肥大化するので、アプリケーションの分割を検討する
  • ホーム機能はOSの“ホーム”やウィジェットの仕組みを活用するなどして、UIの幾らかをOSに委ねる
  • 機能起点ではなくユースケース単位でUIを設計する(後述)
  • UIのドメインの区切り方を再検討する(後述)

iOSやAndroidのホームに並ぶアプリケーション群は、それぞれが一種の「サービス」だと捉えることができます。いわば、便利ツールやインターネットサービスのためのランチャがiPhoneなどのスマートフォンそのものだと考えられるので、そこからさらに奥に大量のサービスが並ぶような独自のランチャを展開するのではなく、アプリケーションを起動した先で一体何ができるのかというのを適切に訴求するUIを提供する必要があります。

ユーザーにとっては、行動の起点はあなたのアプリケーションのホーム画面ではなく、iOSやAndroidが備えるホームもしくは通知画面なのです。

なお、アプリケーションをキオスクモードで動作させる場合には、先ほどと同様に例外扱いになる可能性があります。

設計を「機能」という言葉で考えてしまう

ソフトウェアの開発、特にウォーターフォール的な作り方をする現場では、往々にして機能と呼ばれるものの仕様から定義することから開発を始めます。ですがこの「機能」というものは一体何を指しているのでしょうか。考えてみるとよく分かりにくい言葉です。

  • 「検索機能」「決済機能」など、ざっくりした大きな括り
  • 情報の管理の仕組み、通知の仕組みなど
  • UIのより細かな振る舞い方(例:ボタンを押し込んだらボタンの色が黒く染まり、押下中であることを示す挙動)

いずれも「機能」の範疇にあるように考えられますが、これでは言葉が抽象的すぎて認識のズレを誘発してしまう懸念が高まります。少し言い換える努力をしてみましょう。

設計の目安

機能と呼ばれるものの指す対象がはっきりしないのと、人によって解釈もバラバラになりやすいところなので、違う言葉で区別する方法をとってみましょう。

まずは「機能」を英単語で次のように区別してみましょう。

  • “Feature”(特徴)にあたるもの
  • “Function”(働き)にあたるもの

FeatureとFunction

Feature(特徴)は、LPや広告などで “推し機能” として掲載されるような内容です。その範囲は「検索機能」「決済機能」といったようなざっくりした大きな括りに相当します。この単位のものに “Featrue” や「特徴」の言葉を当てることによって、元々の「機能」の曖昧さから逃れやすくなります。

Function(働き)は、より細かいソフトウェアの振る舞い方を指す言葉です。UIの仕様だとかはこれに含まれるでしょう。このような単位のものに “Function” や「働き」の言葉を当てることによって、同様に元々の「機能」の曖昧さからの脱却や “Feature” との区別もつきやすくなるでしょう。

特徴と働き

ソフトウェア開発のタスクの区切り方で、まずは大きく特徴的な Feature で分類していって、それを実現するための細かな Function を最小の開発チケットにしていけば、「機能」の意味する対象を現実的に捉えやすくなります。

機能起点の設計をしてしまう、ユースケースの軽視

「機能」の言葉が意味する対象を考え直してみると、いわゆる機能起点の開発方法にもアンチパターンが潜んでいそうな気配がしてきます。

機能を “Feature” / “Function” に再分類してみれば、これらが一体何のために検討されているのかも自ずと疑問として浮かんでくるはずです。Function が Feature の実現ための細かな挙動の仕組みやその実現方法だとしたならば、Feature とは一体誰のために存在するのでしょう?

設計の目安

ここで、ユースケースと呼ばれる考え方を導入してみたいと思います。ユースケースとはいわば「ユーザーの用途」を表したものです。ユーザーがどのような意図や用途を持ってそのサービスを利用するのか。利用の根拠となる部分です。

ユースケースを記述する方法はいくつか存在しますが、UMLのユースケース図を活用するのも一つの手でしょう。そのほか、Goodpatchでは構造設計の一例として、ユーザーの振る舞い方(インタラクション)に基づくユースケースモデルの記述方法を採用することがあります。ユースケースモデルの記述は次のような構文で表します。

インタラクションの構文

〈動作主体〉が〈対象〉を〈動作〉する

〈対象〉に対しては操作対象となるモノを当てはめ、〈動作〉に対しては具体的な操作や行動を当てはめます。〈動作主体〉がユーザーの場合とシステムの場合とで互いにインタラクションが起こる様子を記述していって、大まかな挙動の仕方を流れに沿って表します。

事前にユーザーストーリーや仮説シナリオを言語化しておけば、想定するシナリオに対して具体的な行動の連鎖というものを構文で表すことができるので、いわゆるUXリサーチとUI設計がうまく接合する点になります。

また、ユースケースモデルでは既に〈対象(名詞)〉と〈動作(動詞)〉の要素が明らかになっているので、UIで扱う必要のあるオブジェクトや機能のあたりをつけることができます。

このようにしてユースケースをモデルで表すことができたならば、次にユースケース起点の仕様策定を行います。要するに、機能と呼ばれたものの仕様は全てユースケースにぶら下げて、ユースケース単位の優先度付けを行なってゆくのです。ユースケースに一意の番号を振っておけばこれを管理しやすいでしょう。

  • 特にUIに関わる仕様は、ユーザーのユースケース単位で管理する
  • Function的機能の仕様もユースケースにぶら下げる
  • ユースケース単位で実装優先度を設定する
  • ユースケース単位でコンセプトの実現ができているかを評価する
  • ユースケースには一意の番号を割り振る
  • ユースケースの記述には適切なモデルを構築する

ユースケース

このようにユースケースでまず物事を捉えるようにすれば、根拠のない機能一覧だとか粒度のバラバラな機能仕様のようなものは、作られることは無くなります。ソフトウェアはユーザーが使うものである前提を忘れずに、設計する人々(デザイナー)が開発の目当てを見失わないように努力を続けることが大切です。

このような設計プロセスを経て出来上がったプロダクトの一例としては、Goodpatchがかつてデザインと開発のお手伝いをした「ワンキャリアクラウド」が挙げられます。こちらの記事ではあまり設計の詳細までは言及していませんが、その様子の一端は読者のみなさんにもご紹介できると思います。

Goodpatchのデザイン事例:ワンキャリアクラウド

サービス単位でUIを縦割りにしてしまう(スーパーアプリの典型)

サービスとUIの関係(アンチパターン)

アプリケーションのナビゲーション設計で一番の要注意点は、グローバルナビゲーションをサービスで縦割りにしてしまうことです。要するに全く目的も振る舞いも異なるサービスをタブごとに割り当て、タブ間の関連性とタブバーの拡張性を諦めてしまったUIです。特にiOSやAndroidのタブバーはランチャとして振る舞うものではないので、ランチャ化するならば別の表現方法を探る必要があります。

ソフトウェア開発の経験則の一つに「コンウェイの法則」と呼ばれるものがあります。
開発組織の構造が、そこから生み出される製品(ソフトウェア)の構造にそのまま反映されるというもので、仮にタブ毎に開発担当部署が分かれているような開発体制だと、それが反映されるUIの方にも開発組織が抱える課題が鏡のように映り込んでしまいます。タブAの担当チームとタブBの担当チームの連携が十分でないと、UIの方も一貫性が欠落しとんでもない使い勝手のものが出来上がってしまうことでしょう。

開発の都合で作りやすいからとタブ単位などの区切り方で担当を分担してしまうと、ユーザーにとって好ましくない結果に至る懸念がありますので、十分に注意する必要があります。

Tab Bar

また、OSのルールも念頭に置く必要があります。

iOSやAndroidでは、一般的にタブバーのタブ最大数が5個と定められています。6個を超えるタブは「その他」的に一つにまとめるか、タブバーの独自実装で6個以上を無理やり実現するか、別のナビゲーション方法を検討する必要があります。WebデザインではUIコンポーネントを独自に作る発想をしますが、ネイティブアプリケーションでは基本的にはOSが提供する標準コンポーネントに従うものです。独自設計のUIコンポーネントはよく考えて作らないと、開発者にとってもユーザーにとっても得をしない結果が待っています。まずはOSの仕組みやデザイン言語でどのような構造を実現可能なのかを吟味していく姿勢が大切です。

設計の目安

サービスとUIの関係

提供するサービスが多岐にわたる場合、まずはそれらをタブ単位で区切るような設計をやめましょう。

グローバルナビゲーションにタブバーを採用する場合では、提供サービスで縦割りにするのではなく、ユーザーの体験の仕方やユースケースに基づくコンセプトでタブを区切ってみましょう。要するに、ユーザーから見てどういうサービスに触れられるのか/触れ方をするのかを基軸にUIの構造を検討するのです。

ユーザーはサービスやコンテンツに対して…

  • 能動的に触れるか、受動的に触れるか
    → 左側のタブを受動的なUIに、右側のタブを能動的なUIに
  • 最新情報を受け取りたいのか、探しに行きたいのか
    → 更新されたコンテンツなどを配信するのか、ユーザーが自ら検索するのか
  • 自らの手元に情報を蓄えたいのか
    → お気に入り等でストックした情報の一覧の扱い方
  • サービスの享受、情報の取得を習慣化したいのか
    → TwitterのタイムラインのようなUIをファーストビューにする
  • 新たなサービスを見つけたいのか
    → サービスも一つのコンテンツと見立てて、検索の枠組みの中に収める
    → ミニアプリ的な仕組みならば、それをどこに追加できるのかを設計しておく

このように考えてまずはユースケースから検討していくと、ナビゲーション構造の設計もよりやりやすくなると考えられます。サービスが多岐にわたる場合でも、もしサービス間で共有されるようなコンテンツがあればそのコンテンツ軸でUIを検討するのが良いでしょう。

OSが提供する標準のタブバー的ナビゲーションUIは、タブの表示数が最大5個(iPadOSの場合はこの限りではない)の前提で活用するようにしましょう。

さいごに、一つのアプリケーションで扱うサービスの量があまりにも多くなりそうな場合は、思い切ってアプリケーションの分割を検討してみましょう。モバイルアプリケーションで実現できることはせいぜい片手で操作できる範囲のことだと割り切り、1アプリケーション=1サービスくらいの感覚でデザインした方が、きっとユーザーにとってもサービス事業者にとっても分かりやすくなるはずです。作っている人たちにとって複雑なものは、ユーザーにとっても複雑なものです。

クロスプラットフォーム技術を安易に導入してしまう/プラットフォーム固有のデザイン言語の軽視

iOSやAndroidのネイティブアプリケーションを実装する技術とは別に、クロスプラットフォームの技術と呼ばれるものがあります。1つのソースコードでiOS / Android両方に対応できると謳ったソリューションは昔から存在していますが、そこにばかり目が行くと後で強く後悔することになるので、技術の選定には慎重な姿勢をとることが大切です。

そのような技術には、Xamarin, Flutter, React Native, Unity, WebViewベース, Electron(デスクトップ)等々ありますが、いずれにおいても言えることは、結局1ソースで作れたとしてもiOSやAndroidそれぞれのOS技術に精通していないと、正しく機能するアプリケーションを開発することは非常に難しいということです。またUIデザイン観点でいうと、それぞれのOSが定義するデザイン言語が異なるので、iOS風のUIはAndroidに不適切ですし、その逆にMaterial Design風のUIはiOSにとって不適切な表現になります。

結局iOS, Androidそれぞれの技術とデザインに精通していることが求められるならば、初めからネイティブ技術で別々に開発することを目指す道が無難だし、ユーザーにとっても開発現場にとっても安全で質の高いアプリケーションを作りやすいと言えます。場合によっては開発や維持の手間も、個別のネイティブ実装の方が安上がりな上に確実な品質のものを実現可能かもしれません。

「プラットフォームに深く適合していて、うまく機能する」と「とりあえず雑だけれども、それっぽく機能する」は、「機能する」の一点だけ見れば同じようにも感じられますが、全く異なるものなのです。

設計の目安

クロスプラットフォーム技術の導入には主に技術的な判断と事業・経営的判断が伴います。

技術的判断では、特に評価に加わる技術者がクロスプラットフォーム技術の副作用に熟知していて、それらのconsがprosより上回らないと判断できることが必要に思います。OSレイヤーとアプリケーションのレイヤーの間にもう一つクロスプラットフォーム技術のレイヤーが挟まることになるので、一般にはこのレイヤーがもたらす副作用が開発の枷になりやすくことを念頭に導入判断していった方が良いでしょう。

事業・経営的判断では、主に1ソース化による開発コスト削減が目当てになると思いますが、まずクロスプラットフォーム技術の導入が本当に開発コストの削減につながるのかを慎重に判断するのが良いでしょう。前述した通り、各OSの技術に深く精通していないと結局バグ対応や思わぬ対応に追われることになることが経験則的に分かっているので、1ソースでコスト半減には決してならないことを念頭に考える必要があります。

(例えば、iOS版固有のバグに対応したら、同じソースを共有するAndroid版で逆に機能しなくなる等。結局内部でOSごとの複雑な分岐処理が必要になるので、想定した通りにはなりにくい。)

ここで提案したいのがもう一つの観点、UIデザイン的判断です。
前述したように、iOS, AndroidそれぞれのOSが定義するデザイン言語は異なります。iOSのデザイン言語ではAndroidないしMaterial DesignのUIは表現できませんし、Material DesignではiOSらしいUIは実現できません。1ソースではこれらの区別は非常に難しくなりますし、結局どちらかに寄せるとしたら片方のOSのユーザーに対し不適切なUIを提供することになってしまいます。UIデザインの理想では、それぞれのOSの慣しに沿って構築されたUIを提供し、それぞれの環境で正しく適切に振る舞う環境を実現することです。

(GoogleはiOS向けのMaterial Designコンポーネントの提供を最近になって諦め、iOS標準のUIKitでiOSらしいUIを構築することを推奨しています。)

基本的にはクロスプラットフォーム技術の採用は避けるようにし、可能な限りネイティブ技術でアプリケーションを構築しましょう。それでもあらゆる副作用やconsを検討してもそれが必然的であると判断できるならば、クロスプラットフォーム技術を採用してみるのが良いでしょう。

ただし、ゲームの場合は例外でこの限りではありません。

プライバシーを軽視してしまう

Privacy is a human right

プライバシーは人権です。ソフトウェアにおいてもユーザーのプライバシーを踏みにじったりぞんざいに扱ったりせず、丁寧に扱う設計を目指しましょう。

例えば次のようなUIはダークパターンと認められ、実装してはいけません。

  • ユーザーの知らないところで許可なくユーザー情報を収集し、サービス事業者のサーバに送信・蓄積する
  • アカウントの退会への動線を意図的に複雑にする、隠蔽する、あるいは提供しない
  • 必要以上のプライベート情報を収集する(電話番号、住所、性別、年齢等)
  • ユーザーに気づかれないようにカメラやマイクを使って情報を収集する
  • カメラ、マイク、通知、各種センサー等、ユーザー許可が必要なデバイス機能を「許可」させるよう誘導する
  • ユーザーの連絡先情報を説明不十分のままアップロードさせ、個人情報を集める

設計の目安

  • プライバシーに関する事柄や関連機能の利用はオプトインを基本とする(事前にユーザーの許可を得てから適切に情報を利用すること)
  • プライバシーに関する情報を利用する場合でも、ユーザーが任意にオプトアウトできる仕組みを用意する(事後でもユーザーが任意に拒絶の意思表示ができること)
  • OSが定めるプライバシー保護の仕組みに準拠する(OSのプライバシー保護の仕組みを迂回しようとは決してしないこと)
  • 必要以上のユーザーの情報を取得・収集しないこと
  • 可能な限り、ユーザーデータをデバイス内にとどめる仕組みを目指す

おわりに

デザインパターンやアンチパターンと呼ばれるものは、もちろん今回ご紹介したものに限りません。また、パターンを熟知しているからといって良いプロダクトを作れるとも限りません。一番の核心は、パターンの特性を理解した上で、適切に判断し間違いなく適用できる設計能力にあります。これの実現には、熟練のデザイナーやエンジニアでなければきっと難しいことでしょう。

優れたアプリケーションを仕立て上げるためには、適切なパターンを適用する能力とアンチパターンを見極めるための知識や感覚の修得、および十分なデザインと開発の経験が必要です。Goodpatchはモバイルアプリケーションのデザインで豊富な知識と経験があり、そして優秀な人材を抱えています。UIデザイナーはもとより、デザインの形や意図を実際にコードに起こすことができるiOSデベロッパーやAndroidデベロッパーをはじめ、多数のエンジニアが在籍しています。

◆募集中ポジション一覧

ソフトウェアのデザインというものは、デザインの意図を理解することができるエンジニアがいてこそ実現できますから、デザインもエンジニアリング(開発)もまとめてGoodpatchにご依頼くださることが、きっと一番良いプロダクトを実現する近道になるだろうと思います。ぜひご検討ください。