コードの改善、という作業をここ数日ちゃんと向き合った中で気づいたことをまとめてみる。
Overview
あるモデルレイヤーでユースケースごとに無限にメソッドが増えていきそうなポイントをある程度柔軟にパラメータでユースケースを指定して処理を共通化し、コードの見通しを良くする作業です。 該当のコードは僕が現在の案件にジョインしてからも歴史的な経緯を優先してユースケースごとに(同じようなコードが微妙に異なって書かれている)メソッドを追加することで要件の実現を図ってきた箇所であるが、あるユースケースを実現するときに流石にそろそろ限界では?と僕自身が常々感じていたことを改善するために時間を取ってコードの改善を行いました。
パラメータを柔軟に出し入れするために functional options pattern を使ってみたりいろんなコード書きながら、都度方針を説明して、レビューしてもらってあれこれやりくりした結果、ユースケースごとの責務は一つ下のレイヤー(apiとの接合部分)で負わせることにしてモデルレイヤーではユースケースのみを指定するという方針でコードを書き直しました。
※ もっとキレイにリファクタリングできるとbestだったんですが、色々な制約のもとで場所を移す、という方針になりました。(まぁありがちですが)
結果 モデルに露出していた複雑性は一つ下の階層に移動したので、モデル自体はある程度わかりやすくなりました。
わかったこと
以下の2点を痛感しました。
- ある時点で動いているコードの改善は難しい
- 非機能要件を求めるには基礎が必要
ある時点で動いているコードの改善は難しい
コードが動いている という状態はそれ自体に価値があり、それを改善という大義名分のもとにいじることは、いらぬバグを混入する可能性もあり、既存の挙動を保証しないということにも繋がるので、慎重さが求められます。
また、歴史的な経緯があって、 今時点の状態 が作られている、という事実もあるので、その歴史的な経緯を理解した上で、改善の内容を定義(何をもって改善とするのか) して レビューを受ける 必要があります。
つまり、普通に考えれば 超めんどくさい 作業です。しないほうがさっさと次の作業に進めますし、問題を未来に先送りすることそれ自体は悪いことではないと思います。
非機能要件を求めるには基礎が必要
同僚のエンジニアの皆様にも助けてもらいながら、時間はかかったものの、ある程度ステークホルダーが納得する形で改善することができましたが、その議論を進めていく中で自分には 基礎がない ことを痛感しました。
リファクタリング、コードの改善なんていうものは言ってしまえは 非機能要件 であり エンドユーザーにはそれ自体は一切メリットがない ことです。やらなくたってサービスにすぐに悪影響があるわけではありません。(すぐにと言ったのは長期的には悪影響があるからです。ex. 拡張性のなさとかメンテナンス性の低下とか)
実装パターンだったり、設計パターンだったり、そもそもの設計の知識やノウハウが不足していて、議論を追っかけるのが精一杯だったり、僕の見えてなかったところをガンガンfeedbackもらったり、その結果思ったより時間がかかって心折れそうになったり、とまぁこういったことがあって、そこそこ大変だったわけです。
エンジニアとして 機能要件を満たすこと はさほど難しいことではないけれど、一度非機能要件にこだわると基礎が必要になるということを実感しました。
cf. エンジニアになる覚悟 - Speaker Deck
上記のスライドがすごく勉強になります。
このケース以外にもいろんなケースで非機能要件を追求するには、基礎が必要な場面があると思います。
改善しようと思った理由
思ったより大変だったことに対して、避けることもできたんですが、なんでやろうと思ったかと言うと 将来の自分が絶対に今の自分を恨むだろうなー と思ったからです。
改善したかった箇所は僕もずっと触れてる中で「なんで同じような実装があるメソッドが大量にあるねん、ユースケースごとに分けてもいいけど中の実装は共通化しろや」って割と温度感高めに感じていた箇所でもありました。
今まで自分が書いてきた箇所も、ある程度違和感は感じつつ、それに蓋をして、目の前の案件を仕事を進めるためにコードの綺麗さを犠牲にしてきたのも事実です。
今回もそうすることもできましたが、別案件で、今までに想定してなかったユースケースを提示されて、流石にこれを実現するにはまたメソッドと実装を増やすしかないなと感じて、改めてコードを目の当たりにしたときに「これ以上増やしては行けない」という思いがふつふつと湧いてきたし、まだ案件に入っていなかったので、リファクタリングの時間を取るなら今しかないと思って「えいや」で進めました。
違和感で立ち止まる勇気
進めるにあたっての課題感は前述したとおりで、自分には基礎がなかったので、リファクタリングを始める時点でどういう形が最終的にいいのかはイメージしきれていませんでした。
そもそも何がイケててイケてないのか、ということもまだまだわからないことが多いです。でもその中でも、日々コードを書いている中で 違和感 を感じることはできます。
※ ex) なんか同じコード多いなー、とかそういうやつ
エンジニアがコード書いてるときに違和感を感じたときは、多分何かがおかしい(責務とか、設計とか)ことが多いです。
その何かが具体化できなくても、違和感に蓋をせずに一度立ち止まって何がおかしいのか考えてみることは大事です。もしわからなければ有識者に違和感をそのまま伝えてみるのもいいかと思います。
過去の歴史的経緯を知ることで、違和感の正体を具体化し、必要なことが見えてきます。
立ち止まってリファクタリングすることまでできたら最高ですが、違和感を放置せずに、正体を知る努力をするだけでもコードへの理解は一段進むかも知れません。(ほぼ自戒)
仕事を進めることはもちろん大事です。ただ、なにか違和感を感じたときに、仕事の手を止めて考える時間を取るには勇気がいります。
手を止めて改善策を考えた結果、もっと大変になりそう、、、という未来が見えることがあるかも知れません。その結果仕事を進めてるほうが楽だから、とりあえず臭いものには蓋をしておこうと思っても不思議はありません。
でもあえて手を止めて一度考えてみるという機会を設けてみることで、今のコードに対する見方が変わるかも知れません。
安易に安い解決策を求めた結果あとで苦労する or 恨まれるくらいなら今時間とっても大した事はありません。
まとめ
わかる。ただ、ここ数日ツラミの解消作業の走りを少し行なって気づいたことは、よりメタ的な視点での改善、特に非機能要件に関するものは、基礎基本(設計の知識やノウハウ)がないと話にならんということ。
— ema😎⛱ (@ema_hiro) 2018年7月13日
基礎が足りんから、そもそもどう解決すべきかわからんくて、安い解決策に逃げてしまう(自戒)
そもそもの知識がないと、何がイケてて、何がイケてねーのか分からんというのもある。
— ema😎⛱ (@ema_hiro) 2018年7月13日
日々コード書く時に感じる違和感みたいなものは気づいた時に一度立ち止まって考えた方がいいんだろうなーって思うものの、気づくと違和感そのものに慣れてしまって素通り、もしくは臭いものに蓋しちゃうのが常😇
新しく何か作るより、今動いてるものを改善することの方がよほど難しい。
— ema😎⛱ (@ema_hiro) 2018年7月13日
やはり自分は0→1よりも1→10、10→100の方が価値があると思ってしまうタイプ。
なぜなら自分が苦手だから。
せっかく買ってあったのに積読状態だったからこれ読もう