コードの共通化による弊害を実感した話
「なんでも共通化すればいいわけじゃないよ〜」という一見初歩的なネタなのですが
なんやかんやよくぶち当たる壁なので記事化してみました🐈
背景
私が担当しているシステムは、およそ6年ほど運用されています。
6年も経つと、自分が実装したコードを修正することよりも知らない人が実装したところを修正することの方が多くなります。
そのためコードの全体像を把握できておらず、コードレビューやテストを挟んでも、ちょっとした変更が予期せぬところに影響してしまうことが多々あります囧rz。
原因はコードの密結合にあるのですが、せめてこれから実装する箇所についてはそうならないように少しずつ改善していきたい...と考えた時のことをまとめたいと思います。
「コードの共通化」によって困った事例
実際に起きていた困った事例を超ざっくり説明すると以下のような感じです。
いわゆる「顧客管理システム」を担当しているのですが、その保守をする上で困っことがよく起きます。
管理しているのは顧客データなわけですが、「顧客」と言ってもすべてが同じではなく、タイプAとタイプBに分けられます。
タイプAの顧客とタイプBの顧客は共通して持つデータもあれば、それぞれしか持たないデータもあります。
その共通部分を共通コードで書かれていることが多いのです🤔
タイプAの顧客にまつわるロジックに関して修正依頼がきた際に、既存のコードの該当箇所のみ修正すると意図せずタイプBにも同様の修正が反映されてしまいました。。。
そしてタイプBの顧客データを扱っている部署から苦情をもらう...といったことがちょくちょくありました。
ちゃんとテストしていないのが問題では?
コードレビューで漏れているのが問題では?
という観点は今回は一旦無視します😇
事例を元に思ったこと
DRY原則の誤った解釈による「共通化したいマン」
DRY原則とは:「複数の場所に同じ情報が置かれていると変更時に整合性が取れなくなる危険性が高まるため、一箇所で管理して必ずそこから参照するようにすべきとする原則である。」
原則をそのまま受け取ってしまうと「ほへ〜。ジャ、コードの重複は絶対避けよ」となります。
そこで「共通化したいマン」が誕生します。
タイプAもタイプBも一見同じに見えるデータを持っているので、共通化したくなるんんですよね...。
ですが、タイプAとタイプBの顧客は、扱っている部署が異なるのです。
そのため同じに見えるデータのロジックは現在たまたま同じなだけで、考えている部署が異なるのでいずれ異なるロジックになる可能性は大いにあります。
そういったデータは共通化に適していない可能性が高いです。
IF文だらけの分岐地獄
上記のような事例が起きた時に「なるほ、タイプAとタイプBで違うのね、ジャ、IF文で分けたろ」となることもあります。
そして実際にタイプAとタイプBをIF文で分岐させるコードはあらゆるところで散見されます囧rz
分岐後のロジックの規模が大きくなると、単一責任の原則に違反している可能性が高いです。
単一責任の原則とは:「モジュール、クラスまたは関数は、単一の機能について責任を持ち、その機能をカプセル化するべきであるという原則である」
タイプAとタイプBの顧客を同じ顧客と捉えず、別物として捉えてクラス設計する方が良いかもしれませんね。
共通化と分離を正しくするには?
当たり前ですが、「なんでもかんでも共通化すべきではない」と同時に「なんでもかんでも分離すべきではない」ことが言えます。
書籍「良いコード悪いコード」によると、共通化すべきは概念単位と言われています。
事例でいうと、タイプAとタイプBの顧客は概念が異なります。
タイプAという概念の中でとある計算ロジックが度々でてくるようであれば、それは共通化すべき対象です。
ただ、その計算ロジックをタイプBで流用するのは避けた方が良いでしょう。
共通化すべきか、分離すべきかは対象ロジックが同じビジネス概念かどうかで判断する必要があるみたいです。
とはいえ同じビジネス概念かどうかの判断は容易でないことが多い。。。
同じかと思ってたら違かった😇といったこともあるよね。
気づいた時に対処すべきで、IF文とかで対処せずにちゃんと分離できると良さそうです👍
分離する上での注意点も書籍「良いコード悪いコード」に記載ありますのでご興味ある方は8章を読んでみてね。
あとビジネスサイドのことは開発で判断できないことが多いので、要件定義、設計時にドメインエキスパートとしっかりコミュニケーションとることも大事!!
チームで共通認識を持つことも大事
いくら自分が上記のような知見を持っていたとしても、すべてのコードを自分が眼を通すわけではないので自分の力だけだと限界がありますよね。
チームみんなで実装方針の認識合わせをすることも大事そうです🧑💻
感想
簡単のようで簡単じゃないよね〜〜!!!
参照
- 仙塩 大也. (2022). 良いコード/悪いコードで学ぶ設計入門―保守しやすい 成長し続けるコードの書き方. 技術評論社.
Discussion