散文的ブログラミングの哲学につら抜かれたCleanCodeでカルチャーショック体験

    ボブおじさんのProfessionalな哲学につら抜かれた本、CleanCodeを読んだ。

    感想

    めくるめくカルチャーショック体験

    この本は、自分のこれからのコーディングスタイルを変えるかもしれないと思った。 ページをめくる度に、新たな発見と感動を感じた。

    カルチャーショックの詳細は、下の方に列挙するが、ダイジェストを書くと、

    • コメントは嘘
    • 関数は20行以内
    • コードは上から下へ物語のように書く

    つまり一言で言うと、

    文章のようにコーディングする

    ということ。

    散文的プログラミング

    散文的プログラミング、文芸的ブログラミング、それらは考え方としては 知っていたが、所詮は妄想だと思っていた。

    しかし、そのような夢を本気で追求し、かつ実践し、 そのようなことは可能であるということを、具体的な方法で示しているのがこの本。

    この本では、Fitnesseのコードがよく例として引用される。

    それをみると、なるほど完全な文章ではないにしろ、とても綺麗だ。 読んでいて意味が頭に入る。これがCleanCodeなのかと思った。

    道を極めた男の武道書

    この本は、~すべし、~べきというような、断定的な表現が多用される。

    冒頭で、この本はアジャイルマスターによる指南書だとかかれている。

    この本にかかれている方法が絶対ではない、とは思う。 武道にも流派はたくさんある。 この本は、道を極めたある男が記した、免許皆伝のための武道書と見ることができる。

    詳細

    クリーンコード

    プログラミングとは、コードとは

    まず初めに、プログラミングの定義がかかれている。

    • 機械に実行可能なものとするのがプログラミング、こうした仕様がコード

    コードがなくなることはないと語られている。モデル駆動開発がどんどん洗練されて、コードが自動生成されるようになっても、そのモデルを書くことがコーディングだと言っている(と解釈した)コードは要求の表現なので。

    Clean Codeとは

    CleanCodeの定義について、有名人の意見を募っている。一行に要約してみた。

    • ビャーネ・ストラウストリップ・・・エレガントで効率がよいもの、1つのことをうまくやるもの
    • グラディ・ブーチ・・・単純で直接的なもの
    • デーブ・トーマス・・・文芸的であるもの
    • マイケル・フェザーズ・・・気配りがきいているもの
    • ロン・ジェフリーズ・・・重複を減らし、表現力を高め、単純な抽象化をしたもの
    • ワード・カンニガム・・・その言語が、その問題のためにつくられたように見えるもの

    また、CleanCodeを書くため方法はこう書かれている。

    • きれいなコードを書くためには、骨身を惜しまずに獲得した「きれいさ」のセンスをもって、無数の小さな手法を規律を持って適用する必要があります。この「コードのセンス」が必要なのです。
    • 洗練したコードを書くプログラマというのは、まっさらな画面に変形を加えていくことで、エレガントにコーディングされたシステムを造りあげる芸術家なのです。

    エレガントなセンス、という言葉に引っかかった。

    エレガントとは、優雅さ、洗練さとともに、精神性をも意味する。精神性、つまりその人のスタイルで貫かれた洗練さが、CleanCode。 この本にかかれているボブおじさんのスタイルは、まさに個性的なコードだ。

    意味のある名前

    名前づけについては、いろいろな本で語られているので新たに知ったことについてのみ、メモする。

    • 発音可能なものをつける
    • ハンガリアン記法は、悪。

    ハンガリアン記法はコンパイラが型チェックを実装していないときにできたもの。現代のコンパイラは型チェックを行うので、不要。

    • メンタルマッピングを避ける。

    メンタルマッピングとは、読んだ人が、ああこれはこの略だと頭の中で変換する思考プロセス。

    関数

    この章はなかなかカルチャーショックな部分が多く、興奮した。

    • 関数の第一規律は、小さくせよ、第二の規律は、さらに小さくせよ。

    ギャグのような経験則!小さくするための大胆な発言がこの先に続く。

    • 関数の長さが20行に達することなど、ほとんどないようにすべき
    • if文、else文、while文などのブロック文が1行のながさでなければならない。そうすることで、ドキュメントとしての価値も生まれる。
    • インデントレベルは1つか2つ
    • 関数の名前で示される、ある一つの抽象レベルにおけるいくつかのステップでのみ表現されるなら、その関数は一つのことをしています。関数を書く目的は、ある1つのより広い概念を、抽象レベルのいくつかのステップに分解すること。
    • 逓減原則: コードは上から下へと物語のように読める必要がある。関数は、抽象レベルの順番に並んでいる必要がある。
    • switch文は、一度しか現れず、多態オブジェクトを生成し、継承の裏にかくされている場合のみ使う。それ以外はつかわない。
    • 引数は、理想的には0、その次が1、その次が2。3以上は避ける。引数が多くなったらクラスに抽出する。
    • 関数名は、動詞(名詞)の組み合わせ。
    • 出力引数は必要ない、thisが代わりになる。出力引数の使用は避ける。
    • コマンド・照会の分離原則: 関数は、何らかの処理を行うか、何らかの応答を返すか(bool)のどちらかを行うべき。
    • エラーコードはつかわず、例外処理を利用する。なぜなら、コードが単純になるので。try/catch内のブロックは関数として外へ出す。初めにtry-catch-finallyを書く。

    どの発言も、自分にとっては衝撃的だ。しかし、筆者は同じ衝撃をケント・ベッグのコードを読んで受けたそうだ。そして、その衝撃を原動力として、自分の手法や考えを洗練させた。自分もそれに倣いたいと思う。

    コメント

    コメントも刺激的な発言が多く、頭をピリピリさせる興奮を得る。

    • コメントは大して、いやおそらくまったく必要ない!
    • コードでうまく表現するのに失敗したときに、それを補うために使用する。
    • コメントは、メンテナンスされずに嘘が書いてある。コードこそが、真に正確な情報の源。
    • コメントを書く時間があったら綺麗で表現豊かなコードへリファクタリングしろ。

    コメントを文章として書くのではなく、Extract Methodすればよいのか!これが、CleanCodeの極意なのか!

    前の章で、メソッドの長さの目安はせいぜい20行と書いてあった。あまりメソッドの抽出を実施すると、パフォーマンスに影響がでるのでは?

    と思ったが、そのことについては、前に調べたのだった。コンパイラは賢いので、小さいメソッドならばインライン化してくれる。

    組込み開発の二大迷信に挑む!リファクタリングにおけるパフォーマンスとスタックオーバーフローについての数値実験

    中途半端に小さいことは駄目なのだ。コンパイラの進化を信じる。もっと小さくが正義。

    • コメントアウトは、それを削除する勇気がないだけ。60年代にはコメントアウトする価値はあった。現代は、ソースコード管理システムが覚えているので、もはや必要ない。
    • 変更履歴、日誌コメント、これらはソースコード管理システムのなかった時代のもの。全部削除するべきです。

    つまり、ソースコード管理システムで管理するものはソースのなかに書かないということ。こういう考え方もかなりカルチャーショック。

    • 変数にコメントを強要するルールはまったく馬鹿げている。コードを雑然とさせ、嘘を喧伝し、混乱と無秩序へとコードを誘うでしょう。
    • 短い関数に関数ヘッダは不要。関数によく練られた名前をつけ、小さくし、一つのことを行うようにすることは、コメントヘッダをつけることに勝る。

    まったくその通り!仕事だと、自明な関数にも仕事ではコメントを強要される。こういう不自由な規則があるから、メソッドの抽出や名前変更が進まず、モンスター関数が量産される。 関数ヘッダに時間を割くならば、よい関数名や変数名を考えることに時間を割きたいものだ。

    データ・オブジェクトの非対象性

    • 実装の隠蔽とは、抽象化!クラスというのは、変数をゲッタ、セッタを通してクラスの外に伝えるものではない。抽象インタフェースを公開することで、データの実装を知らせることなしに、利用者にデータの本質を操作させる。
    • オブジェクトは、データを隠して抽象化し、データを操作する機能を与える。

    データとオブジェクトの違いを再認識。なにも考えずにgetterとsetterを作るのはpublicにするのと同意。良く考えることにする。

    クラス

    • クラスの規則は、小さくすること。第二の規則は、もっと小さくすること。責務の数で、小さくする。
    • クラスの簡単な解説は、もし、そして、あるいは、しかし、といった単語以外の単語をつかって、25語以内(日本語だと100文字)程度で作成するべき。
    • 単一責務の原則(Single Responsibirity Principle) クラス、モジュールの変更となる原因となるものが1つでなければならない。
    • 多くの開発者は、1つの責務を持った小さなクラスが溢れかえることで、全体を見失うのではないかと危惧しています。

    ある一つの大きな作業を行うために、小さなクラスを渡り歩かなければならないかと心配します。 しかし、小さなクラスの集まりとして構成されたシステムは大きな少数のクラスで構成されたシステムよりも、可動部分がすくない。

    この考え方は実物を見るのが早い。この本で出てくるFitnesseのgithubを除くと、そこには小さく分割された無数のファイルとディレクトリがズラズラとならんでいてビックリした。

    git clone git://github.com/unclebob/fitnesse

    小さなクラスが適切に管理されたディレクトリの中に整然と並んでいる。管理の単位がファイルごとではなくて、サブディレクトリごとなのだ。一つ、抽象度が高いのだ。 これも、カルチャーショック。

    その他

    • 説明的変数。プログラムを読みやすくする強力な手法の1つは、計算の途中結果を変数に格納し、その変数に説明的な名前をつける。
    • 条件をカブセル化する。条件の意図を示す関数で抽出する。
    • 条件の否定形を避ける。否定形の条件は肯定形よりもわかりにくい。