読者です 読者をやめる 読者になる 読者になる

UZABASE Tech Blog

株式会社ユーザベースの技術チームブログです。 主に週次の持ち回りLTやセミナー・イベント情報について書きます。

NewsPicks クラッシュしないアプリ制作の鉄則

f:id:uzabase:20150204153129j:plain

NewsPicksサービスの開発を行っている大川です。

本日はNewsPicksのスマホアプリがどんな設計になっているかを紹介します。社内LTネタを元にしています。

階段の部分はどうやってるの?(『NewsPicksのUIデザイン』
文字が読みやすいように工夫しているの?
などいろいろと観点はあるとは思いますが、まずは全体として絶対に守っている「竜骨」とも言うべきコアの設計についてお話しします。どのアプリでも必ず守るべき鉄則となります。

鉄則とは端的に言うと、
ビジネスロジックをView, ViewControllerに密結合させない
ということです。

まず大前提として、下記の3レイヤーに分けた設計を行います。

f:id:uzabase:20150131232251j:plain

プレゼンテーション層は、ユーザーの操作に従ってViewのコントロールを行います。
ビジネス層は、データそのものや、データの取り扱い責務を担います。Viewへのデータ変更通知も行います。Viewのいかなる変更もビジネス層には影響しません。iPhone / iPad などのデバイスにも依存しない領域です。
データアクセス層は、サーバーのAPIに問い合わせを行ったり、ローカルストレージ(PreferenceやSQLite、WeakCacheなど)にアクセスします。

スマホアプリの最大の特徴は、タッチスクリーンで操作が行われると言うことです。プレゼンテーション層のView, ViewControllerはめまぐるしく生成、消滅を繰り返します。0.5秒も経たずに画面を遷移することもしばしばです。

f:id:uzabase:20150201114808j:plain

ビジネス層のServiceがViewControllerのインスタンスをがっちり握っているとしたらどうなるでしょう。
例えばTechnologyカテゴリのニュース一覧をとってこようとしたとき、サーバーに問い合わせに行って帰ってきたときには、ユーザーはもうTechnologyカテゴリを閉じていて、経済カテゴリを見ているかもしれません。つまり、Callback先のTechnologyカテゴリのViewが既に解放されてしまっているということです。

f:id:uzabase:20150131234158j:plain

メモリ解放が行われた場所にそのままCallbackすれば、必ずクラッシュします。1度アプリがクラッシュすると、84%のユーザーが離脱するというデータもあるようです。
これは大変な問題です。なんとかしなくてはいけません。
ここで、GoFのデザインパターンのうちの "Observer Pattern" が活躍します。

f:id:uzabase:20150131234902j:plain

Observer Patternを使えば、通知の受取人がいなければそのまま無視するだけという構造をつくりだすことができます。
iOSではNSNotification、AndroidではBroadcastReceiverのような仕組みを使うと良いでしょう。

また、1つの要求に対して1つの返事を返す、という構造にしなくて良くなるため、せっかちなユーザーの操作に影響されてシステム全体が遅くなってしまう問題を回避することができます。

f:id:uzabase:20150201001326j:plain

プレゼンテーション層とビジネス層はインスタンスの寿命が全然違うので、Observer Patternによる極めて疎な結合をさせるように心がけるべし、という言い方もできます。 ちなみにViewが解放されるときに必ずObserver解除をしないと、それがクラッシュ要因になってしまいます。

以上が、スマホアプリではビジネスロジックをView, ViewControllerに密結合させないという鉄則でした。

さて、NewsPicksもSPEEDAも積極的にエンジニア採用活動をしております。Uzabaseに遊びにきて、詳しい話がききたい方はこちらから! ↓

100年に一度のメディア変革期!世界一のニュースプラットフォームを創ろう - 株式会社ユーザベースの求人 - Wantedly