A Philosophy of Software Design ch18 Code should be obvious
Code should be obvious
- 不明瞭さは複雑性の2大原因のうちひとつ
- 重要な情報が新参の開発者にとって明らかでないとおこる
- 【補】「数週間後の自分」も含まれると思う
- 重要な情報が新参の開発者にとって明らかでないとおこる
- 本章ではコードの理解しやすさを左右する要因について述べる
- 理解しやすいコード
- あまり考えずにすばやく読める
- 推測が正しい
- 理解しづらいコード
- 理解するのに時間と労力がかかる
- 誤解のおそれも多い
- 理解しやすいコードはコメントが少なくて済む
- 「理解しやすさ」は読み手の心理
- 自分のコードよりも他人のコードに対して気づきやすい
- コードレビューで判定するが最善
- コードを理解しづらくする因子を理解し、よいコードを書く方法を学ぶ
Things that make code more obvious
- 最重要テクニックは既出
- 良い命名
- コードの振る舞いの明確化
- ドキュメンテーションの必要性を減らす
- 一貫性
- 読み手はコードからパターンを認識し、詳細を読み込むことなく推測できる(それは合っている)
- 良い命名
- スペースを賢く使う
- Docコメントのインデント
- 処理のフェーズ間の空行
- 実装コメントの上に空行を置くと、コメントを読みやすくなり特に有用
- コメント
- どうしても理解しづらいコードになることもある
- 【補】例: 区間端を含むのか含まないのか、とか
- このような場合、コメントで情報を補うのが重要
- 読み手の立場に立って、何が混乱の元となりそうか考えて書く
- どうしても理解しづらいコードになることもある
Things that make code less obvious
- コードを理解しづらくするものは数多くある
- 有用さゆえ、理解しづらくとも使うものもあるだろう
- 例: イベント駆動プログラミング
- ドキュメンテーションを添えることで、読み手の混乱を最小化できうる
- イベント駆動プログラミング
- 制御フローを追いづらくなる
- ハンドラは直接実行されない
- 関数ポインタやinterfaceを通じて、間接的に呼び出される
- 何が実行されるかは実行時までわからない
- 正しく動作するという根拠・確信を得づらい
- ハンドラは直接実行されない
- こういった不明瞭さは、各ハンドラのインタフェースコメントに「いつ実行されるか」を記述して補うと良い
- 制御フローを追いづらくなる
/** * This method is invoked in the dispatch thread by a transport if a * transport-level error prevents an RPC from completing */ void Transport::RpcNotifier::failed() { ... }
- ジェネリクスコンテナ
- 宣言と割り当てで異なる型
- 例: メンバ宣言は
List<T>
、コンストラクタでの割り当てはArrayList<T>
ArrayList<T> --|> List<T>
- 非機能的な特性が異なり、「実際の型が何であるか」が利用側に影響する
- 非機能特性の例
- パフォーマンス
- スレッドセーフティ
- 【補】LSP違反
- 非機能特性の例
- 宣言の型を割り当ての型に合わせるべき
- 例: メンバ宣言は
- 読み手の想定に反する
- 例: mainがreturnするがアプリケーションがexitしない
- メインスレッドは終了するが別スレッドが動き続ける
- コメントで明示すべき
- 例: mainがreturnするがアプリケーションがexitしない
Conclusion
- コードが理解しづらいということは、読み手が重要な情報を知らないということ
- コードを理解しやすくするには、必要な情報が読み手に必ず伝わるようにしなければならない
- 方法は3つ
- 必要な情報そのものを減らす
- 抽象化
- 特殊ケースを減らす
- 新たな情報なしにコードを読めるようにする
- 読み手が他のコンテキストで得ているであろう情報を活用する
- 規約に従う
- 読み手の想定に従う
- 【補】一貫性
- 読み手が他のコンテキストで得ているであろう情報を活用する
- コード中に情報をこめる
- よい命名
- コメント
- 必要な情報そのものを減らす
英語
- judicious
- 賢明な