PROMARI JOURNAL

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

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

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

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

PASS IT ON

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

約束は、テストで守る

2ページ目では、Bluesky の名札カードを足しても、共通処理のコードは1行も変わりませんでした。けれど、「コードを変えていない」ことと、「今までのボタンが今までどおり動く」ことは、同じではありません。たとえば、足した名札カードのせいで、X のボタンの並び順がずれることもありえます。OCPの約束、つまり「足しても今までのものは変わらない」が守れているかを確かめる証拠になるのが、テストです。

図5-1 約束は、テストで守る
図5-1 約束は、テストで守る。実測(検証結果)。既存の63件の期待値を1つも書き換えずに通ったことが、「既存のコードを変えていない」ことの証拠になります。図5-1 約束は、テストで守る。実測(検証結果)。既存の63件の期待値を1つも書き換えずに通ったことが、「既存のコードを変えていない」ことの証拠になります。

テストとは、「この入力なら、この結果になるはず」という答えを先に書いておき、プログラムを動かして一致するかを機械で確かめる仕組みです。先に書いておく答えを期待値と呼びます。

今回の検証では、X や LINE の URL の作り方、ボタンの並び、クリックしたときの動きを確かめる Node のテスト63件が、期待値を1つも書き換えずにすべて通りました。これが「今までの振る舞いを変えていない」ことの証拠です。書き換えたのは、共有先の一覧をそのまま書いた「在庫表」のテスト3件だけでした。一覧に bluesky が増えたのだから、在庫表にも1行増えるのが正しい、という種類の修正です。新しく足したのは、3ページ目の textWithUrl を確かめるテスト1件です。

反対に、今までのテストの期待値を書き換えないと通らないとしたら、それは今までの振る舞いが変わってしまったという合図です。足しただけのつもりで、閉じていた共通処理に手が入ってしまったのかもしれません。

たとえば、Bluesky を足したら、X の URL を確かめるテストが落ちたとします。ここで X のテストの期待値を新しい URL に書き換えれば、テストは通ります。けれど、それは「X の URL が変わった」という事実を見えなくしただけです。本当に調べるべきなのは、「Bluesky を足しただけなのに、なぜ X の URL が変わったのか」のほうです。今までのテストは、足したものが今までのものに影響していないかを見張る役目です。落ちたときほど、期待値を簡単に書き換えないようにします。

想定の外は、生成器が止める

差し込み口を用意したら、その口から想定外のものが入り込まないようにすることも大切です。このプラグインでは、それを生成器が受け持っています。3ページ目で見たとおり、名札カードの右側に書けるのは、用意された6つの名前だけでした。そこで、共通処理を直す前の生成器に、textWithUrl と書いた名札カードを読ませてみました。

Shell共通処理を変更する前の生成器に、textWithUrl を書いた名札カードを読ませた結果
$ python3 tools/config.py --config config/share_config.example.toml --generate
❌ シェア設定が不正です: bluesky.toml: params は「SNS 側の項目名 = hashtagsCsv / site / text / title / url / via」の形にしてください

1行目が実行したコマンド、2行目が生成器の返事です。「bluesky.toml の params は、hashtagsCsv / site / text / title / url / via のどれかで書いてください」と、書ける名前の一覧を示して止まりました。一覧に無い名前を書いても、黙ってそのまま動いてしまうことはありません。口の外から入ろうとする変化は、作り直しの時点で機械が止める。だから、名札カードという差し込み口を安心して用意しておけるのです。止まったということは、「その変化は名札カードだけでは足せない」という知らせでもあります。

差し込み口を開けておくことの代償

それなら、あらゆる変化に差し込み口を用意しておけばよいのでしょうか。そうはいきません。差し込み口を1つ用意するたびに、それを持ち続けるための手間が増えるからです。

図5.2-1 口を開けておくことの代償
図5.2-1 口を開けておくことの代償。考え方。口を1つ開けるたびに、決まりと検査と手順が1つずつ増えます。よく来る変化のためだけに開けます。図5.2-1 口を開けておくことの代償。考え方。口を1つ開けるたびに、決まりと検査と手順が1つずつ増えます。よく来る変化のためだけに開けます。

名札カードという差し込み口のために、このプラグインが抱えている手間は3つあります。1つ目は、名札カードの書き方の決まりと、決まりを守れているかを調べる検査です。2つ目は、名札カードを読んでブラウザ用の JavaScript ファイルを作り直す生成器と、その作り直しの手順です。名札カードを足しても、作り直しを忘れるとボタンは出ません。3つ目は、共有先の情報が、名札カードと共通処理の2か所に分かれて置かれることです。「Bluesky のボタンはどう動くのか」を調べるとき、名札カードと共通処理の両方を見る必要があります。

名札カードは、新しい SNS というよく来る変化のためのものなので、この手間に見合っています。けれど、めったに来ない変化のためにまで差し込み口を用意すると、手間だけが残ります。差し込み口は、よく来る変化のためだけに開けるのが、手間との釣り合いの取り方です。

新しい口は、いつ開けるか

では、3ページ目で Bluesky のために足した textWithUrl は、プラグインの本体に入れるべきでしょうか。実は、今回の変更は、まだ本体には入れていません。この記事のために、作業用のコピーで試しただけです。本体に入れるかどうかは、次の3つの問いを順にたどって決めます。

図5.3-1 新しい口は、いつ開けるか
図5.3-1 新しい口は、いつ開けるか。判断の目安(提案)。来ていない変化のために口を開けません。同じ種類の変化が重なりそうになったときに開けます。図5.3-1 新しい口は、いつ開けるか。判断の目安(提案)。来ていない変化のために口を開けません。同じ種類の変化が重なりそうになったときに開けます。

1つ目は、その変化の依頼が、いま実際に来ているか。2つ目は、同じ種類の変化が、ほかにも来そうか。たとえば Bluesky のように「URL を本文に含めて渡す」SNS が、ほかにもあるか。3つ目は、差し込み口を持つ手間よりも、次から書き換えずに済む利点のほうが大きいか。「まだ来ていない変化のために、先回りして仕組みを作り込まない」という考え方には、YAGNIという名前があります。Bluesky を足してほしいという依頼が実際に来て、同じような SNS がほかにも出てきたら、そのときに本体へ入れます。

SOLID の入門書でも、同じ考え方がよく勧められています。差し込み口(抽象化)は、最初から全部の場所に作る必要はありません。種類が増えそうかをいつも意識しておき、実際に増えたときに作れば十分です。すべてに差し込み口を用意するのは、やりすぎになります。

このプラグインの差し込み口

最後に、このプラグインに今ある差し込み口を、まとめて見ておきます。名札カードのほかにも、共通処理を書き換えずに足せる場所が3つあります。

図5.4-1 このプラグインの差し込み口
図5.4-1 このプラグインの差し込み口。現在のしくみ。口はどれも、よく来る変化の側に1つずつ開けてあります。共通処理の中身は、どの口から足しても変わりません。図5.4-1 このプラグインの差し込み口。現在のしくみ。口はどれも、よく来る変化の側に1つずつ開けてあります。共通処理の中身は、どの口から足しても変わりません。
このプラグインの4つの差し込み口
差し込み口置き場所足せるもの
名札カードdestinations/*.toml新しい SNS
サイトの設定config/share_config.toml並び・言い回し・色の上書き
部品の差し替えcomposition/(DI コンテナ)コピーなどの実装の取り替え
知らせ(イベント)document に届く promari-sns-share計測の受け手

名札カードは、新しい SNS を足す場所です。サイトの設定は、ボタンの並び順や、ボタンに出す文字、色を、サイトごとに変える場所です。部品の差し替えは、たとえば「URL をコピーする」処理の中身を、別の作りに入れ替える場所です。どの部品を使うかを composition フォルダの1か所でまとめて決めているので、そこを変えるだけで入れ替えられます。この仕組みを DI コンテナと呼びます。

知らせ(イベント)は、ボタンが押されるたびに promari-sns-share という名前の知らせを出す仕組みです。アクセス解析などのプログラムは、その知らせを受け取って、どのボタンが押されたかを記録できます。4つとも、よく来る変化に備えて1つずつ用意してあります。部品の差し替えは、連載2.5で詳しく読みます。

考えてみる:差し込み口を増やしすぎると、何が困るの?

差し込み口ごとに、書き方の決まり・検査・作り直しの手順が増え、読む人が覚えることも増えます。しかも、使われない差し込み口も、決まりを変えるたびに合わせて直す必要があり、手間だけが続きます。差し込み口の数は、実際に来そうな変化の数に合わせるのがちょうどよく、それより多く用意するのは、将来の自分に手間を前払いするようなものです。

COMMENTS
コメント…

このページ(5ページ目)の感想・質問・設計へのコメント

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 課題・進め方をご相談
送信だけで契約やお申込みが確定することはありません。