PROMARI JOURNAL

OCP――共有先を一つ足したときの差分を追う

作成: / 公開: / 内容更新:

執筆:tamito0201 / 掲載・運営:プロマリ

丸い共有ボタンの裏側を掘る連載の第5回。SOLID の2つ目の原則 OCP を、本物の SNS(Bluesky)の追加を通じて確かめます。名札カード1枚で済む変化と、共通処理のコードを変更することになる変化。差分を1行ずつ追いかけ、閉じる向きは変化の来やすさで選ぶことを、図22点で読み解きます。

PASS IT ON

ひとつの発見を、次の会話へ。

SRP が線を引き、OCP が足し方を決める

前回のSRPと、今回のOCPは、別々の原則に見えて、実はひと続きになっています。

SRP は、「変更を頼んでくる人(依頼主)ごとに、置き場所を分ける」という原則でした。このプラグインでは、SNS 各社の都合で変わる情報は名札カードへ、サイトの運営者の都合で変わる情報は設定ファイルへ、と分けています。

OCP は、そうして分けた置き場所に、足すための差し込み口を用意します。置き場所が分かれているから、「新しい SNS を足したい」という依頼は、名札カードの置き場所に1枚足すだけで済み、設定ファイルや共通処理には触れずに終わります。SRP で線を引いたから、OCP で「その置き場所に足すだけ」が成り立つのです。

OCP を確かめる4つの問い

ここまでの話を、コードの変更を見直すときに使える4つの問いにまとめます。同じ4つの問いで、段階1(新しい SNS)と段階3(新しい動き)を採点してみました。

図7-1 OCP を確かめる4つの問い
図7-1 OCP を確かめる4つの問い。確かめ方の提案。4つとも「はい」なら、その変化に対しては閉じています。「いいえ」が並んだら、口が無い変化です。図7-1 OCP を確かめる4つの問い。確かめ方の提案。4つとも「はい」なら、その変化に対しては閉じています。「いいえ」が並んだら、口が無い変化です。

問いは次の4つです。新しいファイルを足しただけか。共通処理の変更は0行か。今までのテストの期待値はそのままか。足し方が説明書などで決まっているか。4つとも「はい」なら、その変化に対しては閉じています。図7-1 のとおり、段階1は4つとも「はい」でした。段階3は「はい」が1つだけで、差し込み口の無い変化だと分かります。

差し込み口の無い変化が来ること自体は、悪いことではありません。大事なのは、その変化がどのくらいの頻度で来るのかを見て、差し込み口を用意するかどうかを決めることです。

OCP によくある3つの誤解

OCP を読むときに陥りやすい誤解を、3つ並べておきます。

OCP によくある誤解と、この記事での答え
よくある誤解この記事での答え
既存のコードを一行も変えてはいけない閉じるのは、選んだ種類の変化に対してだけ。想定の外の変化が来たら、共通処理を変更してよい
あらゆる変化に差し込み口を作るべき口を開けるたびに代償が増える。よく来る変化のためだけに開ける
設定ファイルにすれば OCP になる設定で選べるのは、共通処理が用意した値だけ。Bluesky の例のように、用意の外の値は設定では足せない

3つの誤解に共通しているのは、OCP を「変更しないこと」だと読んでいることです。OCP が求めているのは、変更しないことではなく、よく来る変化に対して、変更せずに足せる形を選んでおくことです。どの変化を選ぶかは、実際に来た変化を数えて決めます。

もう1つ付け加えると、OCP は、コードを書く前に一度だけ当てはめて終わりのものではありません。最初に選んだ備え方が、あとから来た変化と合わなくなることもあります。Bluesky のような SNS が次々に現れて、「タイトル+URL」の依頼が何度も来るようになったら、そのときは注文票に textWithUrl を足して、備え方を選び直します。どの変化に備えるかは、実際に来た変化を見ながら、少しずつ育てていくものなのです。

手を動かして確かめる

今回の練習は、最近足した機能の差分を、2つに分けてみることです。手元のリポジトリで、最近足した機能を1つ選んでください。次のコマンドで、足す前と足した後のあいだに、どのファイルが何行変わったかを一覧にできます。<足す前> と <足した後> には、それぞれの時点のコミット(変更の記録)の名前を入れます。

Shell足す前と足した後の差分を、ファイルごとに並べる(範囲は手元のコミットに置き換える)
$ git diff --stat <足す前>..<足した後>
図9-1 この回の宿題:最近の機能追加を「足した」と「直した」に分ける
図9-1 この回の宿題:最近の機能追加を「足した」と「直した」に分ける。確かめ方の提案。「直した」に入ったファイルが、その変化に対して閉じていなかった場所です。図9-1 この回の宿題:最近の機能追加を「足した」と「直した」に分ける。確かめ方の提案。「直した」に入ったファイルが、その変化に対して閉じていなかった場所です。

一覧に並んだファイルを、「新しく足したファイル」と「今あるファイルを直したもの」の2つのかごに分けます。直したファイルのうち、在庫表のように「増えたら1行足すのが正しい」ものは、別に数えておきます。残った「直した」ファイルが、その変化に対して閉じていなかった場所です。

この記事で加えた変更の差分も、同じように数えました。

図9-2 追加と修正の差分を数えた結果
図9-2 追加と修正の差分を数えた結果。実測(検証結果)。数えると、段階1は「足した」だけ、段階2は共通処理を変更した分が混ざりました。どこまでが口の内側かが、数で見えます。図9-2 追加と修正の差分を数えた結果。実測(検証結果)。数えると、段階1は「足した」だけ、段階2は共通処理を変更した分が混ざりました。どこまでが口の内側かが、数で見えます。

段階1は、新しいファイル1枚と、設定の1行だけでした。共通処理の変更は0です。段階2と在庫表の修正まで合わせると、8ファイル・18行の追加・6行の削除になり、その中に共通処理(ドメイン層)の変更が3ファイル入りました。どこまでが名札カードで足せる範囲で、どこからが共通処理を直す範囲なのかが、数で見えます。宿題:最近足した機能の差分を、「足した」と「直した」に分けて数える。数えた結果は、このラベルからコメントに残せます。

OCP をプラグインの形として説明し直した記事は、Robert C. Martin のThe Open Closed Principle(2014)です。Meyer の1988年の定義も、この記事に引用されています。Bluesky の投稿画面の入口は、公式ドキュメントのAction Intent Linksで読めます。「触らないはずのコードに手が入るとき」は、連載1.2でも別の角度から扱いました。if で分ける例をランクごとのクラスに置き換える流れと、「種類が増えたときに抽象化すればよい」という考え方は、NakuRei さんの『SOLID原則完全に理解した!になるための本』のオープン・クローズドの原則の章を参考にしました。

まとめと、次回

第5回のまとめです。OCP は、機能を足すことには開いていて、すでに動いているコードの書き換えには閉じている、という形を目指す原則でした。「閉じている」は「もう触れない」ではなく、「ほかのコードが安心して頼れるほど、使い方が変わらない」という意味です。Bluesky を実際に足してみると、名札カード1枚で済む変化と、共通処理のコードを書き換えることになる変化があることが、数で分かりました。

この回で確かめたこと
問い答え確かめ方
何に対して閉じているか新しい SNS(今ある動き・今ある値)Bluesky を足して web/src 0行
閉じていない変化は何か新しい値・新しい動き注文票の3ファイル・動きの分岐8か所
閉じていると言える証拠は既存のテストの期待値を書き換えずに通ることNode 63件がそのまま通った
新しい口はいつ開けるか同じ種類の変化が重なりそうになったとき3つの問いを順にたどる

閉じる向きは、変化の来やすさで選ぶ。よく来る変化には差し込み口を用意し、めったに来ない変化は、来たときに直します。前回の SRP で依頼主ごとに置き場所を分けたから、OCP で「その置き場所に足すだけ」が成り立ちました。

ここで大事なのは、今回の検証で加えた変更を、プラグインの本体にはまだ入れていないことです。Bluesky を足してほしいという依頼が実際に来て、同じような SNS がほかにも出てきたとき、この記事の差分は、そのまま「差し込み口を広げるときの設計図」になります。差分を数えておいたおかげで、広げるとどれだけ直すことになるのかが、もう分かっているからです。

次回は連載2.3「LSP――Copyに「開くURL」を要求すると何が壊れるか」です。今回は、動きの種類(開く・コピー・端末の共有)で分岐する8か所を、差し込み口の無い場所として見ました。次回は、その3つの動きを「同じ共有先」として取り替えられるかを、LSP(リスコフの置換原則)の目で確かめます。コピーのボタンに「開く URL」を求めると、何が壊れるのか。一緒に見ていきましょう。それでは、次回もお楽しみに!

連載の全体像は本編の連載目次へ。前回の2.1「SRP――一つの共有先の定義は、一つの理由で変わるか」、1.2「共有先が増えても触らないコードを決める」とあわせて読むと、名札カードという差し込み口が、どんな原則の上に立っているかが一続きで見えてきます。

プロマリでは、Webサイトの制作に加えて、共有や計測のような「裏側のしくみ」の設計・導入、それらを運用できる人材の育成に取り組んでいます。機能を足しやすい作りをチームでそろえたい方も、お気軽にご相談ください。

Web制作・計測・人材育成のご相談はこちら

COMMENTS
コメント…

この記事全体の感想・質問・設計へのコメント

PASS IT ON

この気づきを、誰かにも。

この記事を書いた人

Takaomi Murasaki

Promari SNS Shareの開発を通して、Webの仕組みや設計の選び方を紹介しています。動く実装と、その判断に至るまでを記事に残しています。

公開記事 10 件

プロフィールを見る
THANK YOU FOR READING.すべての記事へ ↗

FROM INSIGHT TO IMPACT

「できたらいいな」を、
動く仕組みに。

記事で見つけたヒントを、あなたの事業へ。
新しいサービスも、手間のかかる業務も。
いまの課題から、つくるべきものを一緒に考えます。

開発・AI・研修の実績を見る

まだ、仕様書はいりません。

「何から始める?」から、ご一緒に。

課題がまとまっていなくても大丈夫。テーマを選ぶと相談文をご用意します。
連絡先の必須入力は、お名前とメールアドレスだけ。

まずは課題の整理から相談する

ご相談後の流れ

  1. 01 内容を確認
  2. 02 メールでご連絡
  3. 03 課題・進め方をご相談
送信だけで契約やお申込みが確定することはありません。