arveltのソフトウェア技術メモ

Arvelt's software technology memo

CodeComplete上 自分用まとめ

3年前に買ったまま理解できずに放置してたcodecompleteを読み直したので自分用まとめ。これらの項目について説明できるか?

 

「第1部 基礎を固める」

#第1章

・課題定義

・要求開発

・コンストラクション計画

・ソフトウェアアーキテクチャ

・詳細設計

・コーディングとデバッグ

単体テスト

結合テスト

・統合テスト

・システムテスト

・保守

○これらのアクティビティをまとめて「プログラミング」と呼ぶ

 

#第2章

○プロジェクトを反復型か逐次型にするかはメリットデメリットを考慮した上で、その都度決める

 

#第4章

○プログラミング規約をあらかじめ定める

 

「第2部 高品質なコードの作成」

#第5章

○クラスやルーチンを使うのは複雑なものを単純にするため。そうなっていないなら目的を果たしていない

デザインパターンはコミュニケーションを円滑にするために使用できる

○トップダウン、ボトムアップ、プロトタイプ、うまくいかなければ様々な設計手法を試す

○コメント、wiki、議事録、写真、フリップチャート、UML等様々な手法を使い、あるいは組み合わせ、設計を文書化しておく

 

#第6章

○クラスは適切に抽象化する

・抽象化のレベルに一貫性を持たせる

・インターフェースは意味的なものではなく、プログラム的なものにする。→コンパイラでチェック

○クラスは適切にカプセル化する

・メンバデータを公開せず、直接のアクセスは制限する

・クラスの使い方がわからず実装を見なければいけないようなクラスは設計が間違っている

・包有と継承

○クラスとメンバ

・クラスのルーチンはなるべく少なく保つ

・コンストラクタですべてのメンバを初期化する

○クラスを作成する理由

・現実世界のオブジェクトをモデリングする

・抽象オブジェクトをモデリングする

・複雑さを緩和する、あるいは分離する

・実装の詳細を隠蔽する

・変更の影響を限定する

・グローバルデータを隠蔽する

・引数の受け渡しを合理化する

・制御を一元化する

・コードの再利用を促進する

・プログラムのファミルを計画する

・関連する作業をパッケージにまとめる

・特定のリファクタリングを実行する

 

 

#第7章

○ルーチンを作成する理由

・複雑さを緩和する、あるいは分離する

・実装の詳細を隠蔽する

・変更の影響を限定する

・グローバルデータを隠蔽する

・制御を一元化する

・コードの再利用を促進する

・特定のリファクタリングを実行する

さらに

・複雑さを低減する

・中間部分を抽象化する

・コードの重複を避ける

・サブクラスを作成しやすくする

・処理順序を隠蔽する

・ポインタの処理を隠蔽する

・移植性を向上させる

・複雑な論理評価を単純にする

・パフォーマンスを向上させる

 

○ルーチンの名前

・ルーチンが行うことをすべて説明する

・数字だけで区別しない

・関数名には戻り値の説明を反映させる

 

○ルーチンの引数

・引数は入力、変更、出力の順にする

・使用しない引数を作らない

・状態変数やエラー変数は最後にする

・引数を作業変数として使用しない

 

#第8章

○エラー処理

・当たり障りのない値を返す

・次に有効なデータで代用する

・前回と同じ答えを返す

・有効な値のうちもっとも近いもので代用する

・ファイルに警告を残して続行する

・エラーコードを返す

・エラー処理ルーチンを呼び出す

・エラーメッセージを表示する

・処理を中止する

 

「第3部 変数」

#第10章

○変数の宣言と初期化

・暗黙の宣言を無効にする

・宣言時に初期化する

・使用する場所の近く初期化する

・再初期化の必要があるか確認する

○変数のスコープ

・変数の寿命を最小限にする

・ループ変数はルーチンの先頭ではなく、ループの直前で初期化する

・使用する直前まで値を代入しない

・関連するステートメントはまとめる

○変数の目的

・変数を1つの目的にのみ使用する

・変数に隠された意味を持たせない

・宣言された変数がすべて使われているかを確認する

 

#第11章

○変数の名前

・変数の名前で変数の役割を説明する

・プログラム上の名前ではなく、意味上の名前をつける

・複雑なループの場合に、ループ変数には意味のある名前をつける

・ブール変数は真の場合に意味が通る名前にする

・列挙型にはプレフィックスをつける

・ローカル変数、メンバ変数、グローバル変数を区別できるようにする

・型名、名前付き定数、列挙型、変数を区別できるようにする

・言語の標準的な命名規則に従う

・明確な理由がない限り単語の省略形を名前にしない

○変数の名前アンチパターン

・誤解を招きやすい名前は使用しない

・似た意味の名前を複数つけない

・1、2文字だけ違う名前を複数つけない

・同じような発音の名前をつけない

・数字を使用する名前をつけない

・短くするために意図的に綴りを変えた名前をつけない

・英語で綴りを間違えやすい名前をつけない

・標準ライブラリや既定の変数名と競合する名前をつけない

・完全に独断的な名前をつけない

・読みにくい文字を使わない

 

#第12章

○基本データ型

マジックナンバーを使わない

・必要な時のみ0や1を使う

・0除算を考慮する

・型の変換を明示する

・異なる型を比較しない

・整数の除算に注意する

・整数の桁あふれに注意する

・中間結果の桁あふれに注意する

・大きさが極端に異なる数の加算や減産は行わない

浮動小数点は等価で比較しない

・丸め誤差を考慮する

・マジックキャラクタを使わない

・1つ違いのエラーに注意する

・ブール変数を使ってプログラムの文書化する

・ブール変数を使って複雑な評価を単純にする

・列挙型を使ってコードを読みやすくする

・名前付き定数をデータ宣言に使用する

・配列のインデクスが範囲内かを確認する

 

#第13章

○特殊なデータ型

・構造体を使うと、データの関係、処理の単純化、引数リストの単純化に貢献する

・ポインタは慎重に

・グローバルデータを使う明確な理由がないならば使用しない

 

「第4部 ステートメント」

#第14章

○ステートメントの順序

・上から下へと読めるように書く

・依存性が明白になるようなコード構成、ルーチン名、引数名にする

 

#第15章

○条件文について

・正常なケースはifの後ろに書く、例外的なケースをelseに書く

・ifには意味のあるステートメントを書く

・複雑な評価はブール関数の呼び出しに置き換えて単純化する

・一般的なケースから評価する

・default句を使ってエラーを検出する

・breakなし(フォールスルー)は明確な理由がない限り行わない

 

#第16章

○ループについて

・先頭で評価するループはwhileを使う

・末尾で評価するループはwhileは使う

・ループの途中に出口を作るときはwhileを使う

・決まった回数をループさせたいときはforを使う

・ループの入り口は1ヶ所にする

・初期化はループの直前に置く

・空のループを使わない

・ループを終了させるためにループ変数を変更しない

・ループ変数の最終値を使用するコードを書かない

・whileループではブール変数ではなくbreak文を使用する

・contiinu文はループの先頭での評価に使用する

・ループがネストする場合は、ループ変数に意味のある名前をつける

 

#第17章 

○特殊な制御構造について

・読みやすくなるならreturn文を使う

・再帰を使ってできることはすべてスタックと繰り返しでできる、再帰を使う明確な理由はあるか

・goto文は必ず他の制御構造に書き換えることができる、goto文を使う明確な理由はあるか

 

#第18章

○テーブル駆動

・ロジックが複雑ならテーブル参照に置き換えることを検討する

・直接アクセス、インデックスアクセス、段階型アクセス、を使い分ける

 

#第19章

○制御構造

・論理評価にはtrueとfalseを使う

・論理式は肯定的にする

・数値を含んでいる式は数直線の順にする

・論理変数は暗黙に比較してよいが、数値変数は0と比較する

・ポインタはnullと比較する

・中括弧を対で書き始めることで閉じ忘れを防ぐ

・条件文を再評価してネストを単純化する

・break文を使ってネストを単純化する

・ネストしたif文をif-then-else文に書き換える

・ネストしたif文をcase文に書き換える

・ネストしたコードをルーチンとして独立させる

・連続、選択、反復を使えば大抵の構造は表現できる、その制御構造を使うのに明確な理由はあるか

 

Code Complete第2版〈上〉―完全なプログラミングを目指して

Code Complete第2版〈上〉―完全なプログラミングを目指して