SOLID 開放閉鎖の原則を学習中に安定したシステム・製品は開放閉鎖の原則に則っていることに気づいた話

この記事は[設計こばなし Advent Calendar 2023](https://qiita.com/advent-calendar/2023/software_design_talk)の9日目（12/9分）です。

# 概要
今年度SOLID原則の勉強会を開催してきました。開放閉鎖の原則を学習中に安定したシステム・製品は開放閉鎖の原則に則っていることに気づきました。
いくつか私が思った開放閉鎖に則っている安定したシステム・製品の事例を紹介し、どんな特徴があるか考えてみます。

# 開放閉鎖の原則の勉強会について
## 勉強会概要
開放閉鎖の原則の勉強会の概要はこちらです。

https://k-abe.connpass.com/event/297777/


## 勉強会の資料
勉強会の資料はこちらです。

<script async class="docswell-embed" src="https://www.docswell.com/assets/libs/docswell-embed/docswell-embed.min.js" data-src="https://www.docswell.com/slide/5LL836/embed" data-aspect="0.5625"></script><div class="docswell-link"><a href="https://www.docswell.com/s/juraruming/5LL836-2023-10-26-074605">ソフトウェア設計原則【SOLID】を学ぶ #4 開放閉鎖の原則 by @juraruming</a></div>

## 勉強会の録音データ
Xのスペースの録音です。ご興味あれば資料を一緒に見ながら聞いてみてください。

https://twitter.com/i/spaces/1nAKEaOpWzVKL


# 開放閉鎖の原則について
SOLID 開放閉鎖の原則（open/closed principle）の定義についてです。

* 拡張に開かれており（Open）、変更に閉じられていること（Closed）

機能拡張（追加）の際にクライアントコード（機能追加したコードを使う側）に変更が発生しないことです。


# 日常にある開放閉鎖の原則
勉強会開催のため開放閉鎖の原則について学習している・考えてみると様々な製品・事象で開放閉鎖の原則を感じることができました。
開放閉鎖の原則はソフトウェア設計の領域のみでなく、ビジネスを大きくするための考え方など幅広い事象に転用できる、と個人的に思いました。
いくつか私が日常生活で感じた開放閉鎖の原則について紹介したいと思います。
これらの考え方、事象はより良いソフトウェア設計をするためのヒントになりそうと感じています。

## USB
日常にある【開放閉鎖の原則】の考えたときに一番はじめにイメージしたのがUSBでした。つぎの参考資料の説明がわかりやすかったので引用します。

参考資料: [テスト駆動開発による組み込みプログラミング―C言語とオブジェクト指向で学ぶアジャイルな設計](https://www.oreilly.co.jp/books/9784873116143/)
11.1.2 オープン・クローズドの原則（OCP : Open Closed Principle）

> USBポートは規格に準拠したデバイスなら何でも挿せるよう拡張可能だが、新しいデバイスを受け付けるために変更する必要はない。したがってUSBポートのあるコンピュータは、デバイス追加による機能の拡張に対して開いているが、デバイスがUSBに準拠している限り機器構成の変更に対しては閉じていると言える。


## ACアダプタ
写真は私のMacBookのACアダプタです。
ACアダプタを見てこれも開放閉鎖の原則に則っているなと思いました。

![apple_acアダプタ_全体.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/171866/18dd785c-1320-57d6-e59d-bf962dc96a32.png)

こんな感じでプラグ部分が取り外せます。
![apple_acアダプタ_取り外し.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/171866/27c45faf-29f7-3235-f356-1140a9842da2.png)

アダプタは取り外し可能で海外でも使えるように考慮されていると予想できます。
調べてみたら[Apple ワールドトラベルアダプタキット](https://support.apple.com/ja-jp/HT202114)なる製品があり、7種類のアダプタが付属していました。

![Appleワールドトラベルアダプタキット.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/171866/2ddb1c11-bbd9-a68d-cd47-ce765446477d.png)

プラグ部分にバリエーションがあり、プラグ部分を変更しても本体部分に変更が及ばない作りになっている == 原則に則っているといえそうです。


## apt-getコマンド
Linux（DebianやUbuntu）のパッケージ追加コマンドのapt-getについても考えてみました。
パッケージを追加してもLinuxカーネル本体には影響がありません（影響があったら大変ですが・・・）。
拡張に開かれていて、修正に閉じていると言えそうです。


## マクドナルド ハッピーセット リカちゃん
こどもたちが大好きマクドナルド ハッピーセットの玩具 リカちゃんに注目しました。

![リカちゃん全員.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/171866/5241da19-d2f3-3cd2-f51a-29804885d6e7.png)

全キャラの共通事項はつぎがあると思います。
* ポージングが同じ
* メイクが同じ
* ヘアスタイルはパーツ化してあり変更可能

自宅にはつぎのバリエーションのリカちゃんがいます。
* ラプンツェル風
![リカちゃん_ラプンツェル.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/171866/d8c735f4-2202-943f-f838-bc9e6ad01b55.png)

* ドレス着せ替えバージョン
![リカちゃん_ドレス.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/171866/3ddfaedb-5759-efeb-0a76-06ef7ea925a4.png)

* 髪色変化（日光で髪の色が変わる）
![リカちゃん_髪色変化.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/171866/be961a2c-f461-2dc5-f1d0-2cd0e05ea0f4.png)

頭部のパーツに注目して観察しました。頭部のパーツはネジ止めされていました。
頭部をパーツ化する設計でリカちゃんのヘアスタイルのバリエーションを増やすための拡張が可能になっていると思いました。

![リカちゃん_頭パーツ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/171866/f9fbd4ee-8985-5569-d2f8-1624882a3ace.png)

リカちゃんは共通の特性を持ちながらも個性を持つ拡張ができています。
このような商品展開を続けられれば今後もハッピーセットはこどもたちの収集癖と心とおなかを鷲掴みにしていくのだろうなと思いました。
このような製品を多く生産するには生産ラインにも工夫がありそうと思いました。


# まとめ
日常にある【開放閉鎖】に則っていると思われる物について考えた結果、つぎのような特徴があると思いました。

* 拡張しやすくするためのポイントが設計され、用意されている。
例）Apple ACアダプタはプラグの取り外しで様々な国のコンセントに対応可能
例）リカちゃんであればポージング・メイク・ヘアスタイルのパーツ化の共通事項がある

* 拡張はそれ以外の本体部分に影響しないように設計されている
例）Apple ACアダプタはプラグがどの形状になっても本体は変化しない
例）リカちゃんはどのバリエーションでもお人形のベースは変わらない（と思います。設計・製造者ではないので確証はないです）

上の特徴をソフトウェア設計に持ち込めば**拡張に開かれており（Open）、変更に閉じられている（Closed）** 構造になりそうです。

具体的にソフトウェア設計でどうするかについては勉強会資料の原則違反の例（P21〜）、原則に則った例（P43〜）を参照いただければと思います。