Skip to content

Instantly share code, notes, and snippets.

@pokutuna
Created August 9, 2010 03:08
Show Gist options
  • Save pokutuna/514866 to your computer and use it in GitHub Desktop.
Save pokutuna/514866 to your computer and use it in GitHub Desktop.
ぐちゃぐちゃなコードは開発を遅くする
生産性を守るためにはコードを常に綺麗な状態に保つ
書くのは1回、読むのは何回も
2章 意味のある名前
意図が明確な名前にする
なぜそれが存在するのか、何をするのか、どのように使用するのか
もし名前に解説が必要なら、意図が明確な名前ではない
int d //日単位の経過時間
int daysSinceCreation
int daysSinceModification
int fileAgeInDays
単純なコードでも名前のせいで暗黙さが問題になることも
マジックナンバーをなくしてisFlagged? とかにする
偽情報を避ける
他でよくある名前を避ける
実際にList構造で無いものにaccountListというような名前をつけるべきでない
Listというのはプログラマにとってある特別な意味がある
代替としてaccountGroup,bunchOfAccounts,accountsなど
ごく一部のみが異なる名前を付けない
意味のある対比を行う
同じスコープで2つの違うものに同じ名前を付けることができないからといって、
適当な名前を付けてはいけない
変数名に数字を付け加えるとか適当な文字を付け加える方法(ノイズワード)良くない
(a1,a2,a3…) は意図的な名前付けとは正反対なやりかた
void copyChars(char a1[], char a2[])
→ void copyChars(char source[], char destination[])
意味のはっきりしない単語を避ける、Info、Dataなど、ProductData, ProductInfoの区別がつかなくなる
変数名にvariableを含めるとか冗長なの良くない、NameStringよりNameがいい、もしDoubleが入るなら偽情報
moneyAmountとmoney,customerInfoとcustomer,accountDataとaccount,theMessageとmessage、特定の規約が無いと区別がつかない命名はやめる。
発音可能な名前を使用する
genymdhms (generate year month day hour minute second)
会話でのコードについての意思疎通が難しくなる
検索可能な名前を用いる
1文字の名前や数値定数はコードテキストの中から簡単に見つけられない
MAX_CLASSES_PER_STUDENTなら簡単に検索できる、数字の7なら? ファイル名、他の定数定義…
自分の検索しようと思った単語が他でひっかかるのは良くない
1文字の名前は小さなメソッドのローカル変数だけで使うなど、スコープに応じて工夫する
エンコーディングを避ける
型やスコープ情報などを命名に含める必要ない
ハンガリアン記法
当時はコンパイラが型を知らなかったから、今は必要ない
メンバープレフィクス
m_とか要らない、IDEで色つけろや
インターフェイスと実装
形(Shape)のインターフェイスがあり、具象クラスで実装されるとする
インターフェイスを単純にしたほうがいい
IShapeFactory = レガシーっぽい
実装するほうにShapeFactoryImpやCShapeFactoryのほうがマシ
メンタルマッピングを避ける
あなたが付けた名前を、読む人が心の中で別の名前に変換しなければいけない状況をつくってはいけない
問題領域あるいは解決領域で定義されてる用語を使うべき
ループカウンタi,j,kは慣習だからまだいい
意味の分からないa,bや、それがあるからcを付けるとかは最悪
クラス名
クラス、オブジェクトには名詞や名詞句をつける
ex: Customer,WikiPage,Account,AddressParserCustomer
Manager,Processor,Data,Infoなど動詞や曖昧な単語は避けるべき
メソッド名
動詞や動詞句をつける、名詞は良くない
Javaならget,set,isを名詞の前置にするのが普通
コンストラクタがオーバーロードされてる場合、staticなファクトリメソッドを用意し、名前に引数を表現するものを含めるといい
Complex fulcrumPoint = Complex.FromRealNumber(23.0);
のほうが Complex fulcrumPoint = new Complex(23.0) よりベター
気取らない
巧妙な名前は名前を付けた人と同じセンスとユーモアを共有する人にしか覚えられない
明確さ > おもしろさ
言葉を意図に合わせる
1つのコンセプトには1つの単語
複数のクラスで、fetch,retrive,getなどの名前のメソッドを同じ意味で提供するのは混乱を招く
controller,manager,driverの本質的な違いは? 統一しちゃだめなの?
ごろ合わせしない
1つの単語を2つの目的で使用してはいけない
前の規則を守っていれば多くのaddというメソッドが多くなるが引数と戻り値が意味的に同等なら問題ない
別のことをするなら名前をちゃんと変える、insert,appendなど
解決領域の用語の使用
コンピュータサイエンスの用語、アルゴリズムの名前、パターンの名前、数学用語の名前を使うのはまったく問題ない
業務用語から取り出す必要はない
問題領域の用語の使用
処理内容がプログラマチックでないなら問題領域から用語をとってくる
意味のある文脈を加える
firstname,LastName,street,city,state,zipcodeなどの名前は住所になることが明らか
でもstate変数のみがあるメソッドで使われていると分かりにくい
addrFirstName,addrLastname,addrStateなどのプレフィクスをつけると文脈が伝わる
でもAddressクラス作るほうが望ましい
根拠の無い文脈を与えない
短い名前は意味が明確な場合長い名前より優れている
必要以上に文脈を付けるのはやめる
3章 関数
小さいこと!
関数の第一規則は、小さくせよ。第二の規則は、さらに小さくせよ
関数は20行以下で書こう
ブロックとインデント
if,else,whileなどのブロックの中身は1行で書けるぐらいに
関数の中にネストされた構造を置いてはいけない
関数内のインデントレベルは1つか2つ
1つのことを行う
関数では1つのことを行うようにせよ、その1つのことをきちんと行い、それ以外のことを行ってはならない
関数を書く目的は、ある1つより広い概念を次の抽象レベルのいくつかのステップに分解すること
その意味を持ったままさらに分解するのが困難かどうか
関数が1つ以上のことをしていないか調べる、もう1つの方法は、その関数の実装の中から単なる言い換えでなく別の関数を抽出できるかを調べること
関数のセクション
1つのことをしている関数は無理なく複数のセクションに分けることができない
1つの関数に1つの抽象レベル
関数内の文が同じ抽象レベルにあるべき
getHTML() のような高い抽象レベルと pagePathName = PathParser.render(pagePath
のような中間レベルもあれば、.append("\n")のような低い抽象レベルのもある
関数の中で複数の抽象レベルのことを行うと混乱を招く
特定の式が本質的な概念なのか、実装詳細なのコードを読む人が判別できないといけない
コード通読: 逓減規則
コードは上から下へ物語の様に読める必要がある
関数の抽象レベルが降順で読めるようにする規則: 逓減規則
それぞれの関数が次のより抽象度の低い関数呼び出しに繋がっていることが整合性を持った抽象レベル
switch文
その性質上N個のことを行う
レベルの低い処理にのみ使うべき、多態で代わりにする
switch文は大きすぎる、タイプが追加されるたびにswith文が大きくなる、単一責務の原則反する、開放/閉鎖原則に反する
解決策:抽象レベルの最下層である抽象ファクトリに置く
switch文で多態オブジェクトを生成し、継承の裏に隠れて要れば許す
内容をよく表す名前を使う
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment