👻

リファクタリング用トークンで長期間リファクタリング活動

2023/12/18に公開

みなさんリファクタリングしてますか?コードの清掃活動は大事ですよね。
わたしはさっき一つリファクタリング用トークンを消してリファクタリングを成し遂げました。

リファクタリング用トークン

目印みたいなものです。コードはElmですがあまり詳細に触れないのでそれぞれ読み替えてください。

funcA : A -> Html msg

ここに変更したい関数があるとします。この関数を変更してState -> A -> Html msgにしたくなりました。でもfuncAのcall siteがたくさんあってすべてのところ一息に修正するのはとても大変です。例えば100ファイルくらい。引数を変更したので機械的には変更できません。

あなたはこの変更をひとつのプルリクエストでやりますか?そもそもレビューでこの変更に変更されるかもしれません。一気にやるのは大変ですよね?見るほうも大変です。

ということで一旦古いほうをリネームして、

funcA_replaceMe : A -> Html msg

新しいのを作りましょう。_replaceMeである意味は特にないので見たひとが一目で置き換えたくなるようないい感じの名前にしましょう。

funcA : State -> A -> Html msg -- new!

変更ファイル数は変わらないけど関数名のリネームだけなら一瞬だし見るほうもそこまで負担じゃないですね。多分

あとは見かけたらちまちまちまちまreplaceMeをreplaceしていくだけです。いやあ簡単ですね。


だるい。結局だるいのには変わらないのでだるさと付き合いながらやっていきましょう。

別パターン

Table.view : List item -> Html msg

テーブルを表示するとき必ずソートして表示したくなりました。view関数に渡すときにあらかじめソートするという選択肢もありますが、テーブルは必ずソートしておきたいのでview関数にソート用の関数を渡すことにしました。

Table.view : (item -> item -> Order) -> List item -> Html msg

こうしたらどんなテーブルでもTable.view関数を使う限りソートされてることが保証されます。
さっきのようにview自体を二つ用意してもいいですが、ここは別の方法をとります。

defaultSorter_replaceMe : a -> a -> Order
defaultSorter_replaceMe _ _ = EQ

とりあえず新しいview関数を使うところにこの関数を差し込んでいきます。とりあえず各々のテーブルで適切なソート関数を設定するのは一気にやるのは面倒なので後から変更して欲しいことがわかりやすいようにこういったトークンを作って置いておきます。最終的にはこの関数は少なくなっていって最後には消して終了です。

終わり

あるコードに長年付き合ってると、ある変更を加えてもすべての部分に適用するのは大変です。量が多いと時間的にも気力的にも難しいです。そうすると新しい書き方と古い書き方が混在して負荷があがってしまいます。新しくしてもいいところはできるだけ見かけたら新しくできるようにわかりやすくしておきましょう。

Discussion