SOLID原則というのがあるのだけど、原則といつつ やりすぎに注意なみたいなことを言われ、自分で塩梅を探らないといけないなら全然原則じゃないやんということであまり好きではないのだけど、その中でもここではOにあてはまる開放閉鎖原則って意味ないよねって話を。
開放閉鎖原則の原典はメイヤーの「オブジェクト指向入門」で、第2版には次のような記述があります。(初版も書いてることはだいたい同じで、2版のほうが整理されて記述も多くなってます)
モジュールは開いていると同時に閉じているべきである
ただ、このメイヤーの文脈でいうようなモジュールの拡張ってやらないよねと。
ここでメイヤーの文脈での拡張というのは、モジュール自体に手をいれずに、機能の追加や変更ができるというものです。継承使っていい感じに機能追加ができる設計が「拡張に開かれている」ということです。
でもまあ、そんなライブラリの拡張をやらないですよね。やるならソースいじる。
ソースいじって拡張しやすくというのであれば、それはメンテナンスしやすいコードを書きましょうという話になり、拡張だけではないので、わざわざ「拡張に開かれている」を抜き出す必要がないです。
同じようなものが並んでいるところは、同じところを抜き出しておいて、差分だけを並べるようにしておけば、コードの重複が減ってメンテナンスしやすくなりますね。そして、さらにそこに同じようなものを追加することになれば、差分が並んでるところに追加すればいいだけになるため、結果的に拡張しやすいという具合です。そのとき、ちょっと拡張性も意識するといいくらいの話。
あと、マイクロサービスでモジュールをネットワーク経由で呼び出すようにもなっているので、マイクロサービスを他のサービスで拡張したいかっていうと、たぶんないし、あったとして拡張ポイントの提供はめんどくさく危険な割にメリットもそんなになさそう。
「変更に閉じている」 というだけの話なら、カプセル化と同じことになるので新たな用語は不要で。
ただ、メイヤーはこのようなソースコードの修正は複数バージョンを産むことになるのでダメといってます。ここで前提は、複数のモジュール利用者が異なる要求をもちそれぞれにどう対応するかというのが問題意識になっています。しかしそもそも、複数ユーザー向けに異なる機能を提供するシチュエーションがあるかというとないですね。
独自に拡張したい場合はどうかということなのだけど、メイヤーは次のように書いています。
重篤な構成管理の問題が発生している。この問題に人々は複雑なツールを使うことによって対処しようとしている。
ただ、初版の時点ではCVSすら出ておらず、2版もGitの前です。
いまぼくたちにはGitHubがあります。GitHubは複雑ではあるけど、当たり前のツールになっています。
開放閉鎖原則は、環境が変わりすぎているため、もはや意味がなくなっています。
そもそも、想定機能として実装の追加や切り替えができるようにするのならわかるけど、まだ見ぬ拡張に対応するような設計が本当に必要かというのもある。だいたい、無用に複雑になり、作業の邪魔になることはあっても、その複雑さが報われることはない・・・
拡張ポイントのようなものを作るなら、最初のリリース時からその拡張ポイントが複数使われてるようになってないと、いざ拡張するとき結局その拡張ポイントじゃ使えないってなりがち。
要するに、拡張したいところ、できるところというのはモジュールの一部分であり、重複の排除というより一般的なコーディング指標にしたがって差分の集合を抽出することで副次的に達成可能で、また外部的に拡張可能にするのであればそれは製品仕様であり、コード全般にわたって拡張可能性を原則として考えて作業する必要ないよね、ってことです。
ブコメにある、他チームが作ったモジュールで変更できないという状況も、限定された拡張要求にたいして拡張ポイントを機能として提供、もしくは拡張性とかは特に考えずメンテナンス性など汎用のコード品質を考えておけば副次的に満たされるんではという気がします。そうではなく他チームが使うことを想定して変更可能性をそこかしこにあらかじめ埋め込んでおけって話だと、そんなことすれば無用な複雑性に苦しむだけでは。
あと、OCPの定義が違うとかインタフェースがという話だと、SOLIDのI(があればいい
ついでに、ブコメ見ても「開放」に関する議論だけだし、「閉鎖」はカプセル化で十分なので、「openとcloseが同居してておもしろい」くらいしかこのふたつをまとめる理由ないですね。開放のほうはインタフェースの話になるんで、インタフェース分離とあわせて「インタフェースをちゃんと定義しようの原理」みたいなのを考えておけば、特別に拡張のことを考える必要もないと思います。
「全体がそういうわけではない、これが役立つところもある」みたいな話は、そういう環境が限定されて有用なことを開発全般に必須な原理のようにするのも、あまりよくないですね。
引用をストックしました
引用するにはまずログインしてください
引用をストックできませんでした。再度お試しください
限定公開記事のため引用できません。