はじめに
花丸ちゃん、お誕生日おめでとうございます!1 nikkieです。
ミノ駆動本_読書py 第14章『リファクタリング』の事後となりましたが、予習していた事項のアウトプットです。
Uncle Bobの『Clean Craftsmanship』のリファクタリングの章(第5章)を読みました。
目次
- はじめに
- 目次
- 第5章 リファクタリング
- Martin Fowlerの『リファクタリング』を読もう!
- リファクタリングは、ルービックキューブ
- Uncle Bobオリジナル? 「フィールドの抽出」
- 終わりに
第5章 リファクタリング
公開されている目次より
他の章と比べると5章は簡潔です。
本章を意図的に簡潔にしたのは、マーチン・ファウラーの『リファクタリング』に追加したいアイデアが少なかったからだ。繰り返しになるが、リファクタリングを深く理解するには『リファクタリング』を読んでほしい。(Kindle版 pp.258-259)
Martin Fowlerの『リファクタリング』を読もう!
Uncle Bobのお墨付きが出ました!
私もちょっとずつ読み進めていますが、『リファクタリング』、コードの構造を改善する技術が例を通して学べて、めちゃめちゃいい本だと思います。
最近の私を助けている一冊です。
『リファクタリング』で関連するアウトプットがこちら:
- 入門F2 〜VS CodeのRename Symbolで楽々リファクタリング〜 - nikkie-ftnextの日記
- エディタの機能を知って身につけるリファクタリング 〜VS CodeでExtract編〜 - nikkie-ftnextの日記
- 私は「変数の抽出」をリファクタリングテクニックと認識せずにこれまで使っていたのか! - nikkie-ftnextの日記
リファクタリングは、ルービックキューブ
第5章で一番印象に残ったのがこちらのたとえ。
これは本当に言い得て妙だと思うんですよ!
- ルービックキューブは小さい操作を積み上げる
- ルービックキューブは簡単に操作を戻せる(逆操作)
- リファクタリングにも逆操作が存在
- ルービックキューブの操作自体の種類は少ない
- 『リファクタリング』は多くテクニックが載ったカタログだが、頻出のいくつかのテクニックを身につけるだけで多く場面に対処できる
そして、ルービックキューブは手を動かさないと習熟しないように、リファクタリングも練習が必要です。
言い換えると、今はうまくできなくても練習していけば身につけられるということですね。
Practice, practice, practice!!
IDEの使い方を押さえよう
第5章は「名前の変更」や「メソッドの抽出」、「変数の抽出」を紹介したあとで以下のように続きます。
これまでに小さなリファクタリングがいかに強力であるかを説明した。(略) これらのリファクタリングを学び、IDEの使い方とコツを覚えることが重要である。(Kindle版 p.254)
私もおんなじこと考えるようになったんですよね3。
VS Code Conference Japan 2022 - 2023 - connpass
nikkie / 楽々入門!VS Codeで『リファクタリング』
このトークでは、書籍『リファクタリング https://www.ohmsha.co.jp/book/9784274224546/ 』で紹介されたテクニックをVS Codeの操作と結び付けて理解するのを目的とします。
引用した箇所を読んで、「私、クラフトマンシップの道進んでるじゃん!」と嬉しく思いました😃
IDEのリファクタリング操作=ルービックキューブの操作だと思います。
1つ1つでいいので、操作の使い所とIDEの操作を身につけるのがオススメです。
これができるとルービックキューブの操作を1つ覚えた状態になります。
上で挙げた3つの小さなリファクタリングが使えるようになるだけで、開発で取れる選択肢が広がると実感しています。
3つを組合せて簡単にリファクタリングできると経験してからは、私はコードを書くときに悩むことが減りました。
一発で正解は書けないと割り切り、悩むよりも手を動かし、その後はテストコードも用意してよりよい構造にリファクタしていくようになりました。
Uncle Bobオリジナル? 「フィールドの抽出」
『Clean Craftsmanship』で初めて知ったのが、「フィールドの抽出」というテクニック。
先日のエントリはこれを写経するための準備でした。
サンプルコードは、COVIDの新規感染者数を郡と州で合計するコードです。
NewCasesReporter
は長大なmake_report
メソッドを持っています。
class NewCasesReporter: def make_report(self, county_csv: str) -> str: total_cases = 0 # 全州の新規感染者数の合計 state_counts = {} # 州毎の新規感染者数 counties = [] # 郡(County)を入れていく配列(Countyは郡の新規感染者数も持つ) lines = county_csv.split("\n") for line in lines: # 長大なループ(リファクタリング対象) # 上で定義したtotal_casesなどを更新している ... # reportを作成する処理
テストがあるのでリファクタリングは好きなだけできます!🙌
まずmake_report
のループをIDEの機能でメソッドに抽出しようとするのですが、以下のようなシグネチャを提案されます。
def new_method(self, total_cases, state_counts, counties, lines):
これはキャンセルします。
引数を4つも渡したくない。抽出した関数に渡していいのは、配列のlinesだけだ。(Kindle版 p.247)
make_report
メソッドのローカル変数total_cases
などが抽出先の関数のシグネチャに入ってくるのが、メソッドの抽出をキャンセルした理由(の1つ)です4。
これをどう解消するか?
「フィールドの抽出」を使うのです!
やることは、ローカル変数をインスタンスのフィールドに持たせること(だけ)です。
class NewCasesReporter: def __init__(self) -> None: self.total_cases = 0 self.state_counts = {} self.counties = [] def make_report(self, county_csv: str) -> str: self.total_cases = 0 self.state_counts.clear() self.counties.clear() lines = county_csv.split("\n") for line in lines: # 長大なループ(リファクタリング対象) # self.total_casesなどを更新するように変わっている ... # reportを作成する処理
これにより、ループ部分はlines
だけを引数とする関数に抽出できます。
def new_method(self, lines):
写経したコードはこちらです:
https://github.com/ftnext/road-to-craft-skills-py/commits/c3874113fff806d956e559ad54c359f93bed0ba2/covid/report.py
ローカル変数をインスタンス変数に置き換えるというのは、ほとんど見たことがなかったので学びになりました。
Uncle Bobは「それほど使うことはない」と述べていますが、私は読む前はこの発想すら持ち合わせていなかったので、「自分が作ったクラスで、メソッドのローカル変数をフィールドにして、クラスをよい構造に育てていけるかも」と可能性を感じています。
この後は処理のまとまりごとに、インスタンス変数を更新するメソッドへと抽出が進んでいきます。
「フィールドの抽出」をきっかけに、このコードの構造は劇的に改善されます!(さすがです、おじさま(Uncle Bob)。略してさすおじ!)
『Clean Code』ではメソッドの引数は0個がよい(インスタンス変数を使う)という主張だったので、それと重なるな〜と思いました5。
オブジェクトのフィールドが可変になっているので、このやり方について好みは分かれるかもしれないですね。
終わりに
『Clean Craftsmanship』第5章を読んで、リファクタリングの理解を深めました。
私、なかなかソフトウェアが書けないんですよ。
「プログラム書いてるからソフトウェアじゃん」と思われるかもしれないですが、私の書いたプログラムは全然ソフト(変更容易)じゃないんです!(つまり、ハードウェア!6)
このあたりは日々精進という感じですが、打ち手の1つとしてリファクタリングを学び始めたところ、小さい範囲を変更容易な構造にリファクタできたという成功体験を少しずつできており、ちょっとは前進しているのかなという感覚です(まだ全然道半ばですけどね)
-
市役所もお祝い、未来ずら〜
↩【国木田花丸ちゃん HAPPY BIRTHDAY!✨】
— 沼津市役所 (@Numazu_city_PR) 2023年3月3日
本日3月4日は、燦々ぬまづ大使Aqoursの国木田花丸ちゃんの誕生日です😊💮🎉
花丸ちゃん、HAPPY BIRTHDAY🥰🎀
◆観光ポータルhttps://t.co/BXkMrr9lgp
#lovelive #Aqours #国木田花丸ちゃん #沼津 #numa_kanko #numa_1 pic.twitter.com/bGu84wRyHX - え、待って!リファクタリングって1つ1つのステップそんなに小さく実施するの!? (『The Art of Agile Development』読書録) - nikkie-ftnextの日記↩
- ミノ駆動本 14.4にも同様の話題があります↩
- 他の理由は書籍を是非どうぞ↩
- 第3章に「関数の引数は理想的には0」とあります↩
- 今期めちゃめちゃお気に入りの『お隣の天使様にいつの間にか駄目人間にされていた件』、石見舞菜香さん演じる天使様のセリフに「家事ができないのに一人暮らしとか、なめているのですか?」(1話)というのがあるのですが、私はこれを脳内で「変更しやすいコードが書けないのにソフトウェア開発とか、なめているのですか?」に置き換えてぐさっとなりました↩