nikkie-ftnextの日記

イベントレポートや読書メモを発信

読書ログ | 『Clean Code』第3章 〜関数でシステムを話して聞かせる〜

はじめに

これはわたしのストーリー1 nikkieです。

ミノ駆動本 12章「メソッド(関数)」を機に思い出した本をあたっています。
『Clean Code』の第3章「関数」の読書ログを残します。

目次

『Clean Code』第3章「関数」

Uncle BobによるCleanシリーズの1冊。
Cleanなコードを書くためのテクニックが紹介されています。
過去に(ミノ駆動本と関連させて)コメントの章について取り上げました。

Clean Code - アスキードワンゴ

第3章は「関数をうまく書くための方法を解説」する章です。
公開されている目次を見ると盛りだくさん!
以下は特に印象的だった項目です。

小さいこと!
1つのことを行う
1つの関数に1つの抽象レベル
関数の引数
なぜ関数をこのように書くのでしょう?

関数にシステムを語らせる!

関数のあるべき(理想)について、新しい視点を得たように感じます。
この章を読んで知ったことの中で、これが私にとって一番大きいですね。

コードは上から下へと物語のように読める必要があります。(Kindle の位置No.1325-1326 「1つの関数に1つの抽象レベル」)

これは、TO節(LOGO言語の関数定義のキーワード2)の並びとして上から下へプログラムが読める、とも言いかえられています。

それぞれの節はその場所での抽象レベルについての記述を持ち、続く次のレベルのTO節への参照を含みます。(Kindle の位置No.1329-1330 「1つの関数に1つの抽象レベル」)

プログラムの中で関数は抽象レベルの降順(抽象 -> 具体と理解)の順で並ぶのを理想とします。

システムを語らせるために、「抽象レベル」

前提として、小さい関数

Uncle Bobは自身の経験から「関数は小さくせよ!」と主張します。

関数の第一規則は、小さくせよ。第二の規則は、さらに小さくせよ、です。(Kindle の位置No.1245 「小さいこと!」)

エピソードとして、ケント・ベックが書いたプログラムを見せてもらったという話題がありました。
2行〜4行の小さい関数たちからなるプログラムは明瞭だったとのことで、「たしかに読みやすそうだな〜」と感じます。

後年の本ですが、『Clean Craftsmanship』のリファクタリングの章3で、「関数を抽出して、抽出して、抽出しまくるんだ!」という主張がありました。
「その結果小さい関数に至るよな」とつながりを感じました。

1つのことを行う=単一の抽象レベル

1つのことをする関数とは、「ある1つの抽象レベルにおけるいくつかのステップのみで表現される」関数です。

関数を書く目的は、ある1つのより広い概念(これは関数の名前でもあります)を、次の抽象レベルのいくつかのステップに分解することなのです。(Kindle の位置No.1300-1302 「1つのことを行う」)

私も(特に時間のプレッシャーが高いときに)書いてしまうことが多いですが、複数の抽象レベルにまたがった関数はあとで読み返してわかりにくいですし、そもそも長くなりがちです。
複数の抽象レベルの例としては、本質的な概念と実装詳細がごちゃまぜになったコード(リスト3-1)で、「これ、私が書きがちなやつじゃん!」と思い知りました。

思うに、単一の抽象レベルの関数を書くと、1つ1つの関数は小さくなると思います。
小さい関数がずらーっと並んだ状態を想像しています。
ケント・ベックのプログラムの例は単一の抽象レベルの関数からなっていたわけですね。

リファクタリングテクニックの「関数の抽出」で別の関数を抽出できる場合、その関数は2つ以上のことをしている確認になるそうです。

一発でうまくは書けない。だから、リファクタリングするんだよ

「単一の抽象レベルの関数の並びにシステムを語らせるプログラムを書いてみたい!」と思ったわけですが、初手でそれができるほど今の私は強くはありません4
何回かの作り直しを経て、「これもしかしてちょっとは語らせるように作れたんじゃないの!?」と目標状態に近づくでしょう。
ここに関しては文章の執筆とのアナロジーで説明されます。
要は、誰も最初から完璧な文章やプログラムは書けない。だから、草稿を洗練していくんだということです。

関数を書くとき、最初は長く複雑なものとなります。(Kindle の位置No.1669 「なぜ関数をこのように書くのでしょう?」)

次にコードを練って洗練していきます。関数を分離し、名前を変更し、重複を排除していくのです。(Kindle の位置No.1672 「なぜ関数をこのように書くのでしょう?」)

洗練とは、つまり、リファクタリングだと思いました。
最初から完璧なプログラムは書けないので、それを受け入れ、リファクタリングテクニックを使って少しずつでも完璧に近づけていくわけですね(完璧=関数がシステムを語る状態)

終わりに

『Clean Code』第3章の読書ログでした。
ミノ駆動本と関連させてこれまでもたびたび参照していた『Clean Code』の関数の章。
改めて通読したところ、関数をうまく書く(書き直すが正確?)方法がいくつも学べ、また理想状態を知ることもできました!

関数1つ1つは小さく、単一の抽象レベルからなり、それらが抽象から具体に向かって並ぶことで、プログラムがシステムを語る!
そんな"神の一手"のようなプログラム、目指してみたいですね〜。
練習あるのみだ!

この章の内容、けっこうリファクタリングと関連しているように思うんですよね。
関数の抽出や、この記事では取り上げていませんが、パラメタオブジェクトの導入といった点です。
その点でも書籍のコードを写経するともっと理解が進みそうだなと思いました(写経しよう!)

関数をクラスと一緒に使うプログラムはどう並べることでシステムを語らせられるのか、今はよく分かってないのですが、これも写経すると見えてくるかもですね〜

P.S. 4/7(金) 12章「メソッド(関数)」のミノ駆動本_読書py(終)!

次回ミノ駆動本_読書py(Python使い視点でミノ駆動本を読む、みんなのアウトプット中心の読書会)は4/7(金)、なんと最終回です!

常連さんも、お久しぶりの方も、はじめましての方もメソッドに興味ある方、大歓迎です!
ぜひぜひお気軽にお越しください〜


  1. SHINING LINE* の歌詞より。アイカツはいいぞ!
  2. Pythonでいうとdefです
  3. 読書ログがあります:読書ログ | 『Clean Craftsmanship』 第5章、リファクタリングはたしかに"ルービックキューブ" - nikkie-ftnextの日記
  4. ほんのごく一握りのレジェンドを除いて、皆そこまで強くはないのかもしれません