『Clean Code アジャイルソフトウェア達人の技』を読んで心に残った3つのフレーズ

こちらの技術書をざっと読みましたので、心に残った3つのフレーズを紹介していこうと思います。

Clean Code アジャイルソフトウェア達人の技

Clean Code アジャイルソフトウェア達人の技

コメントとは常に失敗なのです。

おそらくこの本を今回読んでいて最もハッとしたのが4章の冒頭にある上の一文です。

コメントを書く目的は、読んでも分かりづらいコードの内容を補足説明するためだと思いますが、コメントなんかなくてもコードを読んでわかるようにできればそれが一番いい、というのが作中での主張です。

「読解しづらいコードになったからコメントを書こう」ではなく、「コメントを書かずに済むようにコードを改良できないか?」と考えるべきなのです。

懇切丁寧なコメントを書くことがよいプログラムへの第1歩だとなんとなく思っていた僕にとっては、かなり衝撃的な主張で、これ以降を真面目に読み進めるようになりました。

ちなみにコメントについては当たり前というか笑ってしまうような記載もありました。例えば「 /* add by alek3 */ やめろ」みたいなことが書いてあり、昔常駐していたプロジェクトに思いを馳せました。

熟練したプログラマなら、オブジェクト指向が常に優れているという考え方が神話であることを理解しています。

「手続き型っぽいコードの書き方と、オブジェクト指向っぽい書き方がある*1」というのはプログラムを書くようになるとすぐに耳にしますが、その分かりやすい例が紹介されていました。 まずは手続き型っぽい書き方は以下のとおりです。

public class Square {
    public Point topLeft;
    public double side;
}

public class Rectangle {
    public Point topLeft;
    public double height;
    public double width;
}

public class Circle {
    public Point center;
    public double radius;
}

public class Geometry {
    public final double PI = 3.141592;

    public double area(Object shape) throws NoSuchShapeException{
        if (shape instanceof Square){
            Shape s  = (Square)shape;
            return s.side * s.side;
        }
        else if (shape instanceof Rectangle) {
            // 四角形面積計算処理
        }
        else if (shape instanceof Circle){
            // 円の面積計算処理
        }
        throw New NoSuchShapeException();
    }
}

次にオブジェクト指向っぽい書き方です。

public class Square implements Shape {
    private Point topLeft;
    private double side;

    public double area() {
        return side * side;
    }
}

public class Rectangle implements Shape {
    private Point topLeft;
    private double height;
    private double width;

    public double area() {
        return height * width;
    }
}

public class Circle implements shape {
    // 略
}

この2つの書き方で、実現できることは同じですが、拡張のしやすい点が異なります。手続き型の場合、新たな関数の追加は容易ですが、新しいクラスを追加するのは手間です。例えば、周りの長さを求める関数 around を追加するのは容易ですが、三角形のクラス Triangle を追加するためには関数を書き換える必要があります。オブジェクト指向の場合は逆になります。

「複雑なシステムでは、新たな関数を追加することよりも、新たなデータ型を追加することのほうが多い」ため、オブジェクト指向を採用したほうがいい場合が多いというロジックです。

小さいこと!

関数であれクラスであれ、とにかく小さく分割することを主張していました。大きい関数やクラスは複雑化し、あとでメンテする人が大変な思いをすることになります。関数に関してはさらに、引数を減らすことも大事です。

クラスを分割する指針として、SRP(Single Responsibility Principle、単一責務の原則)の話も出てきます。どういう状態がSRPであるか、読んでいるだけでは今ひとつわかりませんでしたが、

  • クラスの概要を日本語でおよそ100字以内で表せること
  • 「もし」「そして」「あるいは」「しかし」といった単語が含まれないこと

この2つが満たされているべきと述べられています。

補足

発行日付

この書籍自体の発行は2017年ですが、原書は2008年であり、一部情報が古いところがあります。例えばMapに関する記述であったり、フレームワークの記述であったりです。

デザインパターン

本書ではデザインパターンがいくつか登場しています。例えば、

  • Adapter
  • Decorator
  • Factory Method
  • Template Method

があります。デザインパターンは20以上あり、全部一度に覚えようとするとなかなか大変*2なのですが、今回のように数個再登場するのでいいタイミングで復習することができました。

*1:関数型言語については記述がなかったと思います

*2:Javaを書き始めたころ、結城浩デザインパターン本を読んで挫折した