目次
- はじめに
第1章 わかりやすいコードを書くためのテクニック
1.1 わかりやすいコードとは
- コードの保守性
- わかりやすいコードを書くコツ
- 簡単にできることからはじめる
1.2 変数と定数
- 意味が伝わる変数名を付ける
- マジックナンバーに名前を付ける
1.3 計算式と条件式
- わかりやすい条件式を書くコツ
- 説明用変数を使う
- 条件式を関数化する
- わかりやすい計算式を書くコツ
- 説明用変数を使う
- 計算式を関数化する
1.4 assertの活用
- assert(表明)の使い方
1.5 制御文
- if文の削減と単純化
- 下限値・上限値チェックの関数化
- ラップアラウンドの関数化
- 早期リターンへの書き換え
- 重複した条件式の統合
- 重複した複合条件の統合
- 条件式が直接関係する部分を局所化
- 配列の活用によるif文の削減
- 決定表によるif文の削減
- nullオブジェクトの導入
- for文の削減と単純化
- STLのアルゴリズム関数への置き換え
- 検索ループの分離
- ループ内の不要な条件の分離
- ループの分割
- ラムダ式によるループの一般化
- switch文の削減と単純化
- case内の関数化
- defaultにassert
- ポリモーフィズムに置き換え
1.6 関数
- 関数の基本原則
- 1 つの関数につき1 つの仕事
- 関数を2 種類に分類する
- 関数化のパターン
- 条件式の関数化
- 計算式の関数化
- 条件分岐のブロック内の関数化
- ループの関数化
- ループのブロック内の関数化
- データ変換の関数化
- データ確認の関数化
- 配列アクセスの関数化
- コメント部分の関数化
- 多過ぎる引数の問題
- 欲張りな関数
- クラス化が不適切
- 小さな関数の必要性
- 自己説明的なコードになる
- 単体テストが可能になる
- 小さな関数による実行速度低下
- 関数化の目的は再利用だけではない
- 関数を書くときの心得
- まずは書いてみる
- 最初に書いた関数は下書き
- 問題の本質を理解する
- 読み手の視点で確認する
1.7 クラス
- クラス化のコツ
- 大きな関数を分割する
- 関数名からクラス候補を見つける
- クラス化のパターン
- 重複部分のクラス化
- 組込型メンバ変数のクラス化
- 関数の引数のクラス化
- コンテナのクラス化
1.8 小さなクラス
- Timerクラスの例
- Scoreクラスの例
- 範囲クラスの例
- 2Dベクトルクラスの例
- 整数型の2Dベクトルクラスの例
- 矩形クラスの例
- そのほかの数学系クラス
- typedefの活用
1.9 まとめ
第2章 シンプルな設計のための原則とパターン
2.1 オブジェクト指向設計の基本
- カプセル化,凝集度,結合度
- カプセル化
- 凝集度
- 結合度
- 継承と委譲の関係
- 継承よりも委譲を好む
- 機能の継承と抽象インターフェースの実装
- オブジェクト指向設計の原則
- 単一責任の原則(SRP:Single Responsibility Principle)
- 開放・閉鎖の原則(OCP:Open-Closed Principle)
- リスコフの置換原則(LSB:Liskov Substitution Principle)
- インターフェース分離の原則(ISP:Interface Segregation Principle)
- 依存関係逆転の原則(DIP:Dependency Inversion Principle)
- デメテルの法則
- デザインパターン
- Template Methodパターン
- Strategyパターン
- Stateパターン
- Compositeパターン
- Iteratorパターン
- Observerパターン
- Singletonパターン
- デザインパターンには複数の実装例がある
- デザインパターンを活用する
- デザインパターンを乱用しない
2.2 クラス設計のコツ
- クラス設計の基本
- クラスの役割を考える
- 作業役クラスと管理役クラス
- 仲介役クラス
- 窓口役クラス
- 生成役クラス
- 専用クラスと汎用クラス
- クラスの責任を考える
- クラスの抽象度を考える
- クラスの結合を考える
- 抽象インターフェースの利用方法
- クラスの共通化
- 実装手段の交換
- 変化しやすい部分の分離
- 不適切な結合関係の分離
- パッケージ境界の分離
- 抽象インターフェースは利用者側に持たせる
- 抽象インターフェースは分離と交換をするための道具
- そのほかの注意点やテクニック
- コンストラクタで完全な状態にする
- メンバ関数の呼び出し順番の対処法
- 初期化はコンストラクタ,後始末はデストラクタで行う
- 実装の詳細を隠蔽する名前を付ける
- クラス設計初級編
- 大まかにクラスを洗い出す
- 利用者の視点でメンバ関数の仕様を決める
- メンバ関数を実装する
- 役割と責任を考えながらクラスを分割する
- 結合を考える
- カプセル化,凝集度,結合度の確認
- クラス設計中級編
- 問題領域と実装領域を分離させる
- 問題領域を中心に考える
- 抽象インターフェースで分離する
- より複雑なものは複数の階層に分割する
- クラス設計上級編
- コンセンプトとコンテキストが重要
- 規模に合わせた設計をする
- コードの寿命を考える
- 作業のしやすさを優先する
- 1つの手段にこだわり過ぎない
- いかに書くかではなく,いかに書かないか
2.3 まとめ
第3章 ソースコードの品質計測
3.1 メトリクス計測
- ファイル,関数単位のメトリクス
- コード行数
- コメント行数
- ステートメント数
- 最大ネスト数
- サイクロマティック複雑度
- Halstead複雑度
- 保守性指標
- オブジェクト指向のメトリクス
- 凝集度
- 結合度
- 継承の深さ,子クラスの数
- クラスの重み付けメソッド数
3.2 コードクローン検出
3.3 静的コード解析
3.4 メトリクスの活用法
- コーディング規約として活用する
- コードレビューの優先度として活用する
- メトリクス計測を目的にしない
- メトリクス計測でプログラマの評価をしない
3.5 ツールの紹介
- SourceMonitor
- Cppcheck
3.6 まとめ
次のステップへ~参考文献の紹介
- プログラム設計,コーディング技術
- C++
- メトリクス計測