事始め
本項では、iOSアプリ、あるいはAndroidアプリ開発を行うに当たってこういったことを意識してほしい、あるいはこういったことはやらないでほしいというようなことを整理して記載します。あえてiOS/Androidを分けていないのは、双方に共通する実装における基本的な観点を抑えたいと考えているからです。リーダブルコードとかリファクタリング関係の本とかを読めば書いてはありますが、そうした本になっているとどうしても内容が分厚くなってしまうので、簡潔・単純明快を基準に置いて記載するよう心掛けます。なお、iOSに関するものについてはiOSアプリ開発で気を付けることに記載しておきます。
意識してほしいこと
- 変数名、関数名、クラス名は適切な命名を心がけてください。もしも適切な名前が分からなければ、その関数やクラスの責務が単一になっているか疑ってください。
- コーディングルールは統一してください。フォーマッターを使い、コーディング規約を守るようにしましょう。
- コメントは基本的にドキュメンテーションコメントを採用するのが望ましいです。
- 関数やクラスに対するコメントには「中で何をしているか」ではなく、「なぜその処理をしているのか」を記載しましょう。何をしているかはコード自体で理解できる状態を心がけてください。
- 複雑な条件や深いネストは忌避されます。が、だからと言って全ての条件やネストの中を別の関数に置き換えればいいわけではありません。条件は適切に分けてconstのbool値変数とする、ネストは構造的にそのネストが浅くなるように処理を考え直すことを意識しましょう。
// 複雑な条件なので忌避される
if ( isDebug && isDesktop && !(x > y || y < 100) && isForeground ) { return; }
// 深いネストなので忌避される
if ( isDebug && isDesktop ) {
if ( !(x > y || y < 100) ) {
if ( isForeground ) {
return;
}
}
}
// ↓の方が分かりやすい(命名とかは適当。javaっぽく書いてるのでfinalが分からなければconstだと考えてください)
final boolean canAccess = isDebug && isDesktop && isForeground;
final boolean shouldAccess = x <= y && y >= 100;
if ( canAccess && shouldAccess ) { return; }
- 既存の実装が悪ければなるべくリファクタリングするようにしてください(動いているから触らない、は負債の蓄積でしかありません)。
- 処理速度はアルゴリズムの改善による解決を心掛けましょう。一番の負荷になっている部分を改善するだけでだいぶ違います。
- private、const(final)指定を心掛けましょう。可能な限りのconst指定、private指定がコードの保守性を高めます。
- 「コードの臭い」に合致しそうかどうか意識しましょう。自らのコードを常に綺麗に保つ意識が大切です。
アンチパターン
- ネットからのコピペはやめましょう。参考にするのは問題ないですが、理解しない状態でのコピペはトラブルの元になります。
- 警告(Warning)の放置はやめましょう。クラッシュや動作不良などの原因になります。なるべく最大の警告レベルを維持し、警告0が望ましいです。
- 警告の安易な抑止はやめましょう。いくら警告がうざいからと表示しなければ解決ではありません。
- 「なんとかManager」、「ほにゃららMaster」、「なんたらInfo」、「なんちゃらData」みたいな名前は避けましょう。肥大化します。全てをそこに書けば良いという悪しき風習の原因になります。
- 共通化のためだけの継承やなんでもやってくれる神クラスの作成はやめましょう。責務は適切に分け、単一責務の原則を守ってください。
- 安易なシングルトンクラスやグローバル変数の作成はやめましょう。どこからでもアクセスできる必要のあるクラス、関数、変数はそうそうありません。
- 例外握り潰しはやめましょう。面倒だからと握り潰すと後で不具合になった時の調査が面倒になります。
- 必要以上の実装はやめましょう。「後でこうやって使うかも」みたいな想像で実装すると、90%は無駄になります。YAGNIの法則に従ってください。
アプリの開発におけるその他の私の考え
- 実装と仕様は表裏一体と心得ましょう。実装が複雑な仕様はユーザにとっても複雑な仕様になりがちです。実装が面倒くさいなぁと思ったら、仕様を考え直してみることも一つの手段です。
- 「驚き最小の原則」にあるように、何が起こるのかという期待と実際の挙動が共通するように心掛けましょう。これは仕様においても、実装(例えば関数名など)においても同様です。
- 「ボーイスカウト・ルール」にあるように、何かを変更する際にはより綺麗にした状態にするのは、実装だけの話ではないと思っています。設定に項目を追加するのであれば、その設定画面自体が果たしてそのままで最適なのかどうなのかを検討することも大切です。
その他、雑感
プログラミングに関する原則には様々なものがありますが、それら全てが自分(あるいはあなた)にとって正しいというものではないと思います。
例えばデメテルの法則はフレームワーク的なものを作る上では大切だと思いますが、私の業務上ではそこまで意識しない方が良いコードになることも多いように思います。実際の例で言えば、UIViewの上にUIButtonを置いたカスタムViewがあったとして、そのaddTargetをUIViewControllerに紐付けたい場合、デメテルの法則に従えば、そのカスタムViewにaddTargetのメソッドをラッパーして追加する感じになりますが、そこでラッパーすることによる疎結合さは一体どれほどのメリットがあるでしょうか?(参考:デメテルの法則のメリット/デメリットについて)
原則を知ることは多くの考え方を知ることであり大切だと私は思います。しかし、それ以上に大切なのは、自分自身のコードは誰が見ても分かりやすく簡潔なのか、修正に対する影響が広くないかどうか、そうしたことを常に意識するマインドそのものだと思います。
技術的負債を重ねたコードを修正していくのは精神的にも悪いため、プログラミングを行う皆様が、そしてその上司となる方々が、コードの保守性や簡潔性を維持することの多大なるメリットを認識していただけると幸いだなぁと思う次第です。