エンターテイメント!!

遊戯王好きのJavaエンジニアのブログ。バーニングソウルを会得する特訓中。

【読書ノート】プログラミング作法

きっかけ

どこかでオススメ書籍として紹介されていたから、ぱら見で良さそうだったので購読することに。

まとめも

スタイル

名前

  • グローバルには分かりやすい名前を、ローカルには短い名前を
    • 命名の統一性を重視
    • 関数には能動的な名前を
    • 名前は明確に

【個人の感想】
重要そうなところを抜き出したけど、ローカル変数名の命名には、若干反対である。
使っていいのは、慣例的に短いのを使うところだけだと思う。(for文のiとか)
ローカル変数でも、ある程度の分かりやすさは必要だと思う。
スコープ範囲にもよるが、だいたいコードは肥大化するものなので、短すぎる名前をつけて後々公開するようなら、最初から明瞭さを重視した方がいいと思ってる。

式と文

  • 構造が分かるようにインデントする
    • インデントがあることで構造が分かりやすくなる
  • 自然な形で式を使う
    • 条件式に否定を使うと、間違いが分かりにくくなる
  • 括弧を使って曖昧さを解消する
    • 演算子の優先度の迷いを断ち切る
  • 複雑な式は分割
    • 演算子が大量にあると、意図が分かりづらくなる
  • 明確に書く
    • 小賢いコードを書くやつはド三流
  • 副作用に注意

【個人の感想】
俺流に味付けしてまとめた。
小賢いコードを書くやつはド三流 は、なかなかのネーミングだと思ってる。
ハガレンの1話の神父に対して言った降りて来いよド三流から発想を得た。
たまに、小賢しいコードをマジで書くやつが居るから、困ったもんだ。
俺は、学生のときにそうなりかけたけど、小賢しいコードのせいでコードが読みづらいことに気づいて辞めた。

一貫性と慣用句

  • インデントとブレースのスタイルを統一する
    • ブレース=波括弧。ここでいいたいのは、if ~ else で、波括弧の位置をどうするかって意味
  • 慣用句を使って一貫性を保つ

【個人の感想】
慣用句って、何をもって慣用句とするのだろうな?
それは、お前の中の常識であって、他の人は違うよ?って言われたら、何を信じていいのか分からなくなりそうな気がしないでもない。
こういうのは考えるのが面倒くさいから、フォーマッタを導入して機械的にやるほうが楽だと思う。

関数マクロ

Cの記述ばっかりだったので、スルー

マジックナンバー

マジックナンバー=プログラム中に登場する数値

【個人の感想】
マジックナンバーは、マジで有害だから、存在させないようにするほうが吉。
あと、マジックナンバーを定数化するときに、two = 2 みたいに命名するアホを見たときは、絶句した。
定数化する意味がないから、名前のところを読めって言いたくなる。

コメント

  • 当たり前のことは書かない
    • プログラムの理解を助長するものを書く
  • 関数とグローバルデータにはコメント
  • 可読性の悪いコードは、コメントで補完するより書き直す
  • コードとの矛盾を避ける

【個人の感想】
日本だと、可読性の悪いコードは、コメントで補完するより書き直す は許されない傾向にある気がする。
必要最低限の改修だけしろとよく言われる。
その流れになったのは、無能なコーダーが上位の役職についているからだと思うんだよね。
もしくは、その可読性最悪のコードの影響を理解していないとか。
どっちにしろ、無能が上にいるってことは変わらないな。

アルゴリズムとデータ構造

  • データ量が少ない→単純なテクニックでやる
  • データ量が増大する→スケールアップ可能な設計にする
  • 高度なテクニックは、実際に計測するまで使わない方が無難

設計と実装

  • 設計=言語によらない

インタフェース

  • サービスを提供するコードと、利用するコードの境界にある
  • 実装の詳細を隠蔽する
    • 利用者への影響を少なくする
    • 実装の交換が容易になる
  • 直行性のある小さな単位を選択する
    • 必要以上の機能を提供するのはNG
      • 管理が面倒になる
      • 使いこなすのが難しくなる
    • 必要十分なものを規定する

デバッグ

  • バグを埋め込みやすいパターンを探してみる
  • バグ対応は、横展開とセットで
  • スタックトレースをよく読み、原因を特定するまでは、修正してはいけない
  • 他人に説明してデバック

バグへの対応

  • 再現させる
  • ログファイルを出力
  • UML書いてみる
  • printデバッグ

テスト

  • デバッグ=テストではない
    • デバッグ=コードに問題があるときにすること
    • テスト=プログラムを破綻させるためにする作業

コーディング時のテスト

  • 境界条件テスト
  • 実行前後の変化を検証する
  • アサーション
  • ありえないケースへの対応も考えておく(防御的プログラミング)

系統的なテスト

  • テストは1個ずつ段階的にやる
    • ビッグバンテスト→破綻する
  • 単純な部品からテストする
    • 複雑な箇所からやると、バグの修正が難しくなる
  • 期待値は明確にする

テストの自動化

大量のテストは、注意力が散漫になり、労力もかかる。
テストを自動化して、いつでも気軽に頻繁にテストできるようにすることは、十分に価値がある。

性能

  • 測定→検証のサイクルが基本
  • ベンチマークの結果は、政治的意図があるので、結果は割り引いて考えておく

移植性

環境に依存することなく動作させる理想のこと

移植性が必要な理由

  • 動作環境が決まっていることが少ない
  • 環境は変化する
  • 移植性があるものは優れたものが多い
    • やりすぎは厳禁

言語

  • 標準にこだわる
    • 移植性を高くしてくれる
  • 王道プログラミング
    • 専門用語が出てくるのは、王道ではない
    • 確率されたスタイルをなるべく使う
  • 言語のトラブルスポットに注意する
    • 演算子の評価順
    • 算術/論理シフト

【個人の感想】
「王」って単語に反応しちゃう

隔離

  • システム依存は別ファイルに移動し、インタフェースで隠蔽

データ交換

  • なるべくテキスト
    • 扱いやすい
    • 見やすい
    • 手作業で変更可能
    • バイナリ使う際は、固定バイト順にする

移植性とバージョンアップ

  • 仕様を変えるなら名前を変える
    • 解釈が変わる→意図的に別のソフトウェアが生まれるようなもの
    • 仕様が変わる=意図しない移植上の問題が発生する可能性が高い
  • 後方互換を維持する
    • 手段が変わる=影響範囲大
    • 非互換性は、コストと相談

国際化

  • 英語を前提にしない
    • 漢字等が入れば、文字サイズも変わる
    • エラーメッセージに業界用語や特定言語のスラングはやめる

感想

ところどころ端折ったが、既存の考えと大筋変わらない。
古典っぽい内容だったな~というのが正直な感想。
リーダブルコードで事足りそうな気がしないでもない。