More Related Content More from Nobuyuki Matsui (15) 良いコードとは5. 読みやすい書き方
• 適切なネーミングを行う
• その変数や関数がやりたいことを端的に表現する明確な単語を選ぶ
• getなどの関数名や、resultといった変数名は、中身が何なのかわからない
• 明確な単語に情報を付加すると良い
• ファイルサイズを格納する変数には、uploaded_file_mbにするとか
• tmpやbufのような、汎用の名前は避ける
• ただし一画面で収まるスコープに限定される変数名の場合、使っても良い
• ループ変数などもスコープが限定されるため、i や j で良い
• 明確な名前が選べなかったり、非常に長い名前を付けたくなる場合は、
適切なモジュール分割ができていない
• canvas_max_pxって付けたくなる場合、max_pxをインスタンス変数に持つ
Canvasクラスが存在するのでは?
9. 読みやすい書き方
• 適切なコメントをつける
• 「プロジェクトルールだから」と、意味のないコメントは付けない
• そのクラスやメソッドを実装しようと思った意図や設計思想をコメントする
• そもそもコレは何をするためのものなのか?
• なぜこのロジックを選択したのか?代替手段はあったのか?
• 自分で微妙と思っている箇所もコメントする
• 例えば
• このロジックは動作するけれど、データ量に対して計算量がO(n^2)になる
• このメソッドは破壊的なので、一度呼び出すと内部データは変更されてしまう
• コードを見たらわかることはコメントしない
• 処理の手続きをコメントしなければ理解できないコードは、「悪い」コード
20. コードを再構成(リファクタリング)する
• the Open-Closed Principle(OCP)
• 「ソフトウェアの構成要素は、拡張に対して開いていて、修正に対して
閉じていなければならない」
• OCPが意識されているモジュールは、修正しても他のモジュールに
影響を与えない
=オブジェクト指向設計の原則
• API仕様の重要性
• 外部に公開しているAPIの仕様(公開されているメソッドのINPUTに対して何
がOUTPUTされるか、その際に発生する副作用は何か)が変わらないので
あれば、中のコードが書き換わっていても誰も気にしない
21. コードを再構成(リファクタリング)する
• 関数の副作用とは
• (数学的な意味の)関数=入力を出力に変換するモノ
• 入力を出力に変換する以外に、関数外部の環境へ影響を及ぼす行為
=副作用
• ファイルやネットワークの入出力、画面の入出力、データベースの入出力
などは全て副作用
• 関数外部の変数への入出力も副作用
• 副作用がない関数は、いついかなる状況で呼び出しても必ず同じ結果
• テストしやすく堅牢なモジュールになる
• 関数型プログラミング言語は、基本的に副作用の無い関数でシステム
を組み立て、副作用のある行為を限定することで堅牢なシステムを作る
• ただし「副作用」が全くないシステムには意味が無い
22. コードを再構成(リファクタリング)する
• 関数型プログラミングのエッセンスを取り入れる
• 変数のスコープはなるべく小さくする
• グローバル変数は敵
• 値を代入するのは一回だけ(同じ変数の使い回しや書き換えはしない)
• ループ変数など小さな関数内部に限定された変数は書き換えても良い
• 暗黙的に依存する変数を書き換えるような関数を作ると、思いもよらない箇所
で変数が書き換わるややこしいバグを生む可能性がある
• list.append()なども、変数の中身を書き換えていることに注意
• 例えばリスト内包表記を用いれば、元のリストはそのままで新しいリストが生成される
>>> x = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> y = [i * 2 for i in x if i%2 == 0]
>>> y
[4, 8, 12, 16, 20]
>>> x
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
24. コードを再構成(リファクタリング)する
• the Single Responsibility Principle(SRP)
• クラスの役割はただ一つだけ
• クラスのコメントに、「このクラスはXXをする役割を担う」と一文で表現できな
ければならない
• クラスの実装を変更する理由は、その「XXの役割」に拡張や修正があっ
たときだけのはず
• 「XXの役割の修正」以外の理由でプログラムを修正する際に、なぜか「XXの
役割」のクラスに修正が入るようであれば、クラスの分割が間違っている
26. コードを再構成(リファクタリング)する
• コードの適切さを評価するために、メトリクスを活用する
• 凝集度と結合度
• モジュールのOCPやSRPを計測する尺度
• 凝集度は高く、結合度は低いのが望ましい
• コードメトリクスツールで数値化することができる
• 細かい数値にはあまり意味がなく、ざっくりとした傾向を見るために用いる
• McCabeの循環的複雑度
• コードの複雑さ(ループや分岐の度合い)を計測する尺度
• 一般的には、10以下が良いと言われている
• 30を超えると構造的に失敗したモジュールと言われており、50を超えるとテスト不
可能で、75を超えると微細な修正であってもバグが混入するらしい
27. テストできるように書く
• 副作用のない関数は、容易にテストできる
• なるべくシンプルに、網羅的に
• ただし闇雲に様々な値でテストを書くのではなく、なぜその入力で
テストをするのか、明確な理由を考える
• 限界値
• 期待している値の最大値を+1超えた値、最小値を-1した値等
• 特殊値
• 数値ならば0
• 文字(utf-8)ならば、ビットパターンが1byteになる文字(US-ASCII文字)、2byteに
なる文字(ギリシャ文字等)、3byteになる文字(常用漢字や丸数字等)、4byte以上
になる文字(JIS X 0213の第3・4水準漢字)など
• 文字(Shift-JISやCP932)ならば、「表」や「ー」など2byte目が0x5c(バックスラッ
シュ)になる文字や、CP932からUTF-8に変換することによって化ける文字(~)等