日々常々

ふつうのプログラマがあたりまえにしたいこと。

リファクタリングに関する何か

リファクタリングの話をするとき、焦点が合ってないなーと感じることがたまにあるのでざっくり描いてみた。

f:id:irof:20200811115944p:plain

自分のために描いたものなので、なんか違うなーって思ったらご自身で描いてみるといいと思います。レッツモデリング

破線は依存、実線は変換。長方形は名前などで明確に識別可能なもの、角丸は様々なものを包含する活動。雲は思いです。

描いた時の経緯と言うか

f:id:irof:20200809211246p:plain

該当ツイート: リファクタリングって常時やるものなんですよね。もちろん「よーしやるぞー」って感じで行うものもあるんですけど、それは深呼吸的な。

とは言え。やったことがない、やってはいけない文化(動いているコードに触ってはいけない)に染められてしまっている、そのような方に「無意識にやれ!」と言っても、何の意味もないので言いません。むしろ害悪ですらある。

f:id:irof:20200809211308p:plain

該当ツイート: 無意識にやるようになって、ようやく「リファクタリング」がカタログ化される前の「偉大な習慣」に入門したあたりになると思ったり。 習慣にするまでは意識してやると思うんですが、習慣になったら意識しなくなるかなって。そんな感じ。

ポイント

偉大な習慣が「リファクタリング(活動)」で、しっかり定義されていないふわっとしたものなので角丸で示してます。 その中から言葉をつけてカタログ化された「リファクタリング(テクニック)」が提供する焦点はいくつかあって。

  • 名前付けによる識別
  • コードの不吉な臭いに依存する、正当化による後押し
    • これがあるおかげで「何となくキモチワルイ」を変えて良くなります
  • 外的振る舞いを守る検証方法に依存する、手順
    • これがあるおかげで「変えても大丈夫」って言えるようになります

で、リファクタリングでたまに微妙な方に行くのが「検証方法」の焦点が合ってないところ。 「外部的振る舞い」ってなんやねんってやつですね。

書籍「リファクタリング」では堅実なテストは事前条件とされています。そして自動テスト前提で書かれています。

これはもちろん(定義者が言っているからって理由を抜いても)正しいのですが、かといって「自動テストがないものはリファクタリングと呼ばない」と強固に主張したところで、それはそれで重要な場面もあるんですが、多くの場面では意味のない話です。「じゃあリストラクチャリング(もしくは他の何かしらの造語)でいいです」とか言葉を変えることにあまり意味はないですし。

と言う事で、検証方法にいろんなパターンがあるとしています。「コンパイルエラーにならない」が保てている限り安全と断言できる変更はあるわけですから。 私が重視するのは「このリファクタリングではこの検証方法を使っている」が示せる事です。 その検証方法の精度は二の次。まずはそれを識別できていること。 識別できさえすれば、その検証方法の妥当性は考えられますし、精度をあげることもできます。 検証方法が思い至らないのであれば、それは流石にリファクタリングじゃないかなって。

まとめと参考書籍(2020-08-10T12:00 追記)

リファクタリングに取り組むと「外部的振る舞い」の扱いに悩むかと思います。 自動テストがあると言っても、それで十分に保つべき外部的振る舞いが検証できてるか確信が持てないこともあるでしょう。

「この外部的振る舞いを保たねばならない」と言う唯一絶対の正解はありません。 重要なのは 保つべきものを見極め、それを検証できる形にしてから取り組むこと です。 これを保てるならば変更していい。そう言う拠り所を作れば、コードをみたときに感じるモヤモヤ(図の気になること)に向き合えます。 リファクタリングは「なんか気になる」などの感情を押し殺さず、むしろこの感性を育み、良いコードを書けるようになる最短ルートだと思っています。

コードの変更は多くのところに波及します。影響を及ぼさないように設計していれば、簡単な検証で賄えるかもしれません。 安定依存の法則に従ったモジュール設計を行っていればより達成しやすくなります。この辺りの話はClean Architectureが参考になります。

(同心円な図がよく挙げられる本ですが、本書の主眼はあの図ではありません。他のCleanシリーズと同様、考え方の本です。)

様々な責務が複雑に絡み合っていれば、包括的で堅牢な自動テストがないと厳しいかもしれません。 そう言うときは、レガシーコード改善ガイドが参考になると思います。

リファクタリングは誰かの許可を貰ってやる物ではありません。できる裏付けを自身で構築してから取り組む物です。 自分で「変えても大丈夫」と言えず、なぜコードを変えられようか。

あと言っておきたいこと

f:id:irof:20200809222051p:plain

該当ツイート: 日常的にやっているからこそ、重要なときにもできるんです。緊急時の規律。

システムの根幹をリファクタリングしたければ、呼吸のようにリファクタリングするようになっておきましょう。 素振りの習慣もないのにいきなりフルスイングしても、色々壊すんですよ。打ちっぱなしでゴルフクラブすっぽ抜けて思いっきり投げた私が言うんだから間違いない。(ちなみに小学生の頃。いまだにトラウマ。)

あ、呼吸のようにやるようになると、コミットに紛れ込みやすくなります。細かくコミットする習慣とどちらが勝るかの勝負になってきます。これどっちがいいとかも文脈依存で、どこに価値を見出すかと言う話です。これはこれでいつか掘り下げたい。