新規Androidアプリ開発において何より大切なこと

この記事は [Android Advent Calendar 2017](https://qiita.com/advent-calendar/2017/android) 7日目の記事です。

当初は設計の話を書くつもりだったのですが、 ~~明日のShibuya.apkで話すネタに困ったので使い回しの効く話題にしたかった~~ その設計が期待通りのものになっているかどうかの検証ができていないので、開発全般のお話になりました。
設計の話題についてはまたどこかでお話できるかなと思います。

以下、エモい話です。


# 対象読者

この記事は以下のような方を対象として書いている…つもりです。

* 職業Androidエンジニア
* 自社サービスの開発に携わっている、またはアプリの開発を受注した方
* コードベースが何もないところから開発をすることになった、または開発をしたい方


# はじめに結論

開発を成功させるには、プロダクトオーナーとの意見のすり合わせが大切です。
事前にオーナーにヒヤリングを行い、エンジニアの見解を伝え、目指す目標を共有しましょう。
Androidアプリ開発の際は、以下のヒヤリングシートを使うとすぐにでもヒヤリングを始められます。

https://docs.google.com/document/d/1Y5M1PGgCssanKe8jaOXGDtMMnddG2cxXacgyXI64POs/edit?usp=sharing


# 前置き

10月から新規アプリの開発を担当しています。
チームでAndroid専任エンジニアは私一人だけという、見方によっては心細い状況です。
（もう一人Androidエンジニアは居られるのですが、Android開発へのジョインは年明けから）

サービス自体はiOSで提供されていて、私に任せられたのはそのAndroid版の開発でした。

開発を始めて2ヶ月。
進捗ペースに若干の不安はある（何分手が足りないもので！！）ものの、

「この設計で開発を進めていて大丈夫なのだろうか…」
「ここは後回しにしてしまっても良いのだろうか…」
「これはもう少しディティールに凝った方が良いのでは…いや、そんなことはない…？」

といった不安に苛まれることもなく、比較的悠々自適に開発をエンジョイできています。

こうした不安の少ない開発「環境」を用意するために、私が取った手法をお伝えしたいと思います。


# アプリ開発において大切なこと

**「コンセプトが決まれば、戦略も戦術も全て自ずと決まる」**

という言葉を聞いたことがあります。
アプリケーション開発についても同様で、アプリケーションのコンセプトが決まれば大抵のことが自然と決まります。

さて、それでは「アプリケーション開発におけるコンセプト」とは何のことでしょうか？



# コンセプト探し

あなたご自身がサービスやアプリの立ち上げに一から関わっているのではない場合、作るべきアプリのコンセプトを持っているのはプロダクトオーナーになります。

まずは **プロダクトオーナーにヒヤリング** をしましょう。


最低限聞くべきことは以下の項目です。

1. アプリが提供する重要な価値
2. 開発リソース
3. コードベースの寿命


具体的に解説していきます。


## 1. アプリが提供する重要な価値

アプリを通して、何をユーザー様に提供したいのか？

サービスやアプリの存在価値であり、利用してもらえる動機であり、収益を得られる理由でもあります。

エンジニアもこれを把握しておく必要があると考えます。
「どのような箇所では手を抜いて、どのような箇所は詳細までつめる」といったメリハリをつけることができるためです。

例えば独自な形状のボタンを実装する必要があるとします。
そのボタンは重要な機能を提供するものではない、apkのサイズが多少大きくなっても構わない、といったことがわかれば、エンジニアは以下のような行動を取ることができます。

* ボタンの背景画像shapeで描画せずをpngで出力してもらい、XMLを書いて試行錯誤する時間を節約する
* `state_pressed="true"`, `state_enabled="false"` などの場合の背景画像を用意せず省力化する

逆に、ユーザー様に一番の価値を提供する画面で主な役割を果たすボタンは、見た目もよく、押したときや押せなくしたときも紛らわしくないようにしたいですよね。


## 2. 開発リソース

正確には、ファーストリリースまでに使用できる開発リソースです。
ここで、開発リソースとは以下のことを指しています。

* 残りの開発期間
* エンジニアの人数とレベル
* 有料ライブラリなどに使用できる予算

例えば、アプリの規模に対して開発期間が短すぎる場合、期待通りの期間に開発を終わらせることは当然困難になります。
そうしたことがわかれば、開発期間の延長やスキルレベルが確かなエンジニアの増員を依頼するなど、交渉を行うことができます。

また、リリース後は以下の事柄も気になるでしょうから、わかる範囲で教えてもらうと良いかと思います。

* 更新のペース
* 大規模な機能追加や施策の予定の有無
* 増員/人員削減の予定
* 他言語対応の予定


## 3. コードベースの寿命

`想定していた保守コスト < 実際にかかる保守コスト` となったときが、そのアプリのコードベースの寿命です。

アプリを長年運用していれば、必ずソースコードは複雑化していきます。
開発メンバーも入れ替わり、歴史の語り部は失われていきます。
新しいアーキテクチャも流行するでしょうし、ライブラリも新陳代謝していく必要があります。
ファーストリリース当時はそれで良かった仕様が、後になって大きく形を変えるかもしれません。
（そして往々にして仕様は変わります）
大きな改修が、既存コードとの一貫性を失わせることもあるでしょう。

そうして積み上がったソースコードは、次第に開発の足を引っ張り始めます。
私が昔担当していたプロダクトでも、新機能追加の前に

「既存の実装に影響が出ないか調査する」

というタスクが積まれていて、そしてこのタスクを消化するのに丸一日〜数日かかることがありました。

そうした状況を打破するためにはリファクタリングが必要です。
そして大規模なリファクタリングのためには、そのための開発リソースを確保する必要があります。
場合によっては、リファクタリングの期間中は新機能の追加を待たねばならないかもしれません。
これはビジネス的には痛手です。

コードベースの寿命は必ず来ますが、永遠に引き伸ばすわけにも行かない。
ならば、ある程度コントロールしてしまおう、そのためにプロダクトオーナーとも寿命をどのくらいにするか話し合っておこう、というわけです。


## テンプレート

私が実際にヒヤリングした際に使用したものをベースに、一般化したヒヤリングシートを作りました。

https://docs.google.com/document/d/1Y5M1PGgCssanKe8jaOXGDtMMnddG2cxXacgyXI64POs/edit?usp=sharing

よろしければお使いください。
ライセンスはCC By 4.0ですが、実際にヒヤリングに使用するときなどは著作者表示は消してしまって構いません。
修正の提案など大歓迎です！

（Google Docsにしたのは、コピーしてちょっとばかり編集して、そのまま担当者に送り飛ばす、ということができるようにするためです。
が、いかんせん管理が面倒なのでGithubに移したりしたいとも思ってはいます…
実際に使われた方は、どのような形式であると嬉しいかなど、教えていただければ幸いです）


## 共通認識

ヒヤリングを通して、プロダクトオーナーとの間に共通認識を作っておきます。

例えば開発にかかる期間について「○ヶ月かかる」という共通の認識があれば、「もっと早く完成すると思ってたのに」といった「期待はずれ」の結果を生む可能性が少なくなります。

このコンセプトの共通認識の有無が、開発時の安心感につながります。

## 注意

プロダクトオーナーであっても人の子です。

プロダクトオーナーの側でも、まだ決まっていないこと、詳細を詰めきれていないこと、今後調査が必要なことなどがあるはずです。
まだ決まっていない、などの返答を返されても「プロダクトオーナーなのにわからないんですか」など、煽ったり圧力をかけたりする発言はしないようにしましょう。
（昔、開発リーダーみたいなことをやったときにこれに近いことを言われ、胃が痛くなりました）

むしろわからないこと、決まっていないことがあって当然です。
そうしたことがあれば、ヒヤリングは複数回実施し、一緒に考えましょう。
オーナーとしても一緒に考えてくれる人の存在は有り難いはずなので、あなたのことを良く評価してくれる材料になるかもしれません :wink: 

# コンセプトから戦略・戦術へ

ヒヤリングができれば、取るべき戦略や戦術が見えてきます。

* 設計
* 使用するライブラリ
* 使用言語
* 力の入れ方/力の抜き方
* レビュー方針
* などなど



![Untitled (1).png](https://qiita-image-store.s3.amazonaws.com/0/41896/c8caceae-85d9-70ab-76c0-65ddd050ef08.png)



以下では、典型的なコンセプト例と、その場合の戦略や戦術について例示します。

## とにかく早く、価値を顧客に届けたい

リーン・スタートアップなどで言われるMVP(Minimum Viable Product)を要求されている場合です。
正式にサービスが走り始めている段階ではないことも多いでしょう。

想定される規模は大きくないでしょうし、もしオーナーが要求する規模が大きいようでしたら縮小を提案すべきだと思います。
正式にサービスインすると決まった段階まで保つコードベースであれば、要求は満たせるはずです。

* 設計
    * Activityべた書きでもよい
    * 神クラスの誕生も仕方ない
* 使用するライブラリ
    * それっぽい機能のものを片っ端からつかう
    * もしくは、ライブラリのあれこれに惑わされないように自力で突っ走る
* 使用言語
    * 開発陣が最も使い慣れている言語
* 力の入れ方/力の抜き方
    * 新機能の追加や仕様変更に真っ先に取り組む
    * エラー処理などは、データが消失しない限りおざなりでもよい
    * エッジケースでクラッシュしても修正は後回し
* レビュー方針
    * 知見共有のためにさらっと見るだけ
    * もしくは、レビューせずにマージでも良いかもしれない
* その他
    * ドキュメントを書いているヒマはない
    * 動作確認は人力で


## 既にiOS版があるので、そのAndroid版を作って欲しい

Android版に独自の役割や機能を要求されていない場合、基本的にiOS版の仕様をなるべくそのままAndroid版に実装することになります。
サービスは軌道に乗り始めていて、Android版にはさらなる売上向上が求められているとします。

この場合はiOS版に何を求めているのかもヒヤリングした方が良いでしょう。
iOS版で求められたことがそのままAndroid版にも降ってくることになるためです。
iOS版にて頻繁に仕様の変更が行われているようなら、Android版でも仕様変更に耐えられるようにしておきましょう。


* 設計
    * 小規模なMVP, MVC, MVVM, Reduxなど
    * 更新ペースが早いなら、画面ごとに違うアーキテクチャを採用できるようにするのも手
* 使用するライブラリ
    * 開発陣のレベルに合わせる
        * ReactiveXが苦手、という人がいるようなら、代わりにArchitecture Componentsを使用するなど
* 使用言語
    * Kotlinで速度を出す
* 力の入れ方/力の抜き方
    * Androidユーザーにとって使いやすいよう、マテリアルデザインガイドラインに準拠する
    * iOS版でも使用頻度が低い画面はレイアウト作成に時間をかけすぎない
    * 不安にな箇所はテストを書く
* レビュー方針
    * 変なコードを書いていないかどうかだけチェック
    * あるいは、デバッグに十分なリソースを確保できない場合は動作確認まで
* その他
    * なるべくドキュメントコメントを残す
    * 自動テスト、自動デプロイの環境を整える
    * Robolectricを使ったLocal Testくらい


## 数千万人が使用することが予想されるアプリを作りたい

比較的十分に予算と時間とエンジニアリソースがある場合です。
新卒のエンジニアが配属されていて、先輩のエンジニアにはその育成も期待されてるとします。


* 設計
    * Clean ArchitectureやFluxなど大規模/大人数開発に耐えられるもの
    * 機能はモジュールで分割して役割分担が簡単なように
* 使用言語
    * 育成対象の方に覚えて欲しい言語など
        * 今だとKotlinだと思いますが…
* 使用するライブラリ
    * RxJavaなど定番どころ
    * ハイクオリティな有料なもの
    * もしくは要件にあうものを自前で作成
* 力の入れ方/力の抜き方
    * 主機能の完成度を高くするのは当然として
    * クラッシュの発生率は低くても絶対数が多くなってしまうので、エラーハンドリングは慎重に
* レビュー方針
    * 育成対象には、設計のイロハを教えながら、命名やtipsまで細やかに
    * ベテランのPRは知見共有を主目的としてレビューする
* その他
    * 環境構築、設計方針からAPIまでドキュメント化
        * 属人性が高まると困る（キーマンが抜けると破綻する）ので属人性を排す
    * 単体テストはもちろん、UIテストなどで品質をある程度担保


# おしまいに

アプリケーション開発の際は、アプリ開発のコンセプトを明らかにしておくことで、その後の決め事をスムーズに行うことができます。
また、プロダクトオーナーとコンセプトの認識を合わせておくことで、安心して開発を進められます。

コンセプトを明らかにし、認識を合わせるためには、ヒヤリングを行いましょう。
その過程でエンジニアの意見も伝え、お互いが納得できるようにしましょう。

[テンプレート](https://docs.google.com/document/d/1Y5M1PGgCssanKe8jaOXGDtMMnddG2cxXacgyXI64POs/edit?usp=sharing) もありますので、ぜひ使ってみてください。

それでは、今年も来年も、楽しく開発をしましょう！