オープン・クローズドの原則って頭で分かっていても難しい
タイトルそのままなのですが、オープン・クローズドの原則って頭で分かっていても難しいなあと思います。
今回は難しいなあ難しいなあと思ったことをただそのまま書くだけの記事です。
オープン・クローズド原則とは
オープン・クローズド原則とは、変更に対してはクローズドであり、拡張に対してオープンであるべきといった原則です。
SOLIDの原則のうちのひとつです。
何が難しい?
オープン・クローズド原則の解説は、多くの人がさまざまな例を用いて解説してくれています。
解説用に作成されたサンプルコードはとても分かりやすく、読んだときはなんとなく理解した気持ちになります( ◠‿◠ )(会員に応じて割引率が変わるという仕様の場合、会員の種類が増えた場合に既存コードを変更しなくてすむような実装にしようね、みたいなものとか)
オープン・クローズド原則を守る実装にする方法としては、インターフェースや抽象クラスを使うなどがあります。
使い方についてはすでにある解説の記事を見ればすぐに理解できます。
ただ難しいのは将来的に仕様が変更される可能性の高い不安定な領域と、安定させたいコアな領域を見極めることです。
前回の記事に通ずるところですが、何が安定していて、何が不安定なのかをコードに落とし込む前に理解しておく必要があります。
それはつまり、実装者はシステムの側だけでなく事業や業務について深く理解しておく必要があるということです。
オープン・クローズド原則を守るHowの部分だけでなく、Whyを追求する力が必要なことも頭に入れておく必要がありますね。
ちょっとした例
私が担当するシステムでは「インボイス制度」導入による改修がありました。
改修当時は、以下の3つのステータスしか考慮していませんでした。
- 適格請求書発行事業者に登録していない
- 適格請求書発行事業者に登録済みかつステータス有効
- 適格請求書発行事業者に登録済みかつステータス失効
しかし、適格請求書発行事業者には取消と取下げというステータスもあることが設計から漏れていました。
それらのステータスを追加した際に変更したファイル数は、16ファイルでした。
これが多いか少ないかはシステムによるかもしれませんが、弊システムでは比較的多いと判断される改修だったと思います。
適格請求書発行事業者に対して「適格請求書発行事業者が失効しているかどうか?」のチェックをしているすべての箇所で、取消および取下げのチェックも追加で入れる必要があり、変更箇所が多くなりました。
今回の件だと、本質部分は以下だったと言えます。
- 何らかのルールによって、適格請求書発行事業者が有効であるかどうかが判定される
ここの「何らかのルール」はその事業者が持つステータスによって異なります(失効年月日を持つ場合は登録年月日<=現在日付<失効年月日であること、など...)
そのルールの多様性をインターフェースや抽象クラスなどでうまく表現できていれば、コードの変更箇所を少なくすることができていたかもしれません。
拡張を意識しすぎると冗長なコードになってしまいますが、実装時に「拡張の可能性を考慮できているか?」「この仕様で変更される可能性の低いコアな部分は何か?」などは考えるようにしたら良いかもですね。
感想
みなさんは「オープン・クローズドの原則」を考えながら実装できていますか?
仕様のコアな部分とそうでない部分を分離して考えられていますか?
私は...微妙かもー!
てか実装時に考えないといけないこと多すぎないですか?助けて!AI!
でも「仕様のコアな部分とそうでない部分を分離する」部分はまだAIに任せられないところ
他の細かいところをAIに任せて、そういったところに頭を使えるようになりたいですね!
Discussion