SRP――一つの共有先の定義は、一つの理由で変わるか
作成: / 公開: / 内容更新:
執筆:tamito0201 / 掲載・運営:プロマリ
丸い共有ボタンの裏側を掘る連載の第4回。SOLID の最初の原則 SRP を、共有先の名札カード1枚からプラグイン全体まで当てて確かめます。責任とは仕事の数ではなく、変更を頼んでくる人の数。Martin の車の修理のたとえから、実際の変更履歴を数える宿題まで、図22点で読み解きます。
もし名札カードに並び順を書いていたら
分けておくと何がうれしいのかは、分けなかった場合を考えるとよく分かります。仮に、x.toml に「大きく出すかどうか」を書く primary という行を足していたとしましょう。SRPの目で見ると、何が起きるでしょうか。
X が共有画面のURLを変えたとき、x.toml を書き換えます。サイトの運営者が X を小さいボタンの列へ移したいときも、x.toml を書き換えます。関係のない2つの依頼が、同じ1枚のカードでぶつかるのです。この状態には発散的変更という名前が付いています。サイトの判断を名札カードに書かないことで、カードの依頼主を1人に保っています。
ぶつかるのは、書き換えるときだけではありません。2人が同じ週に同じファイルを書き換えると、あとから取り込むほうは、相手の変更と自分の変更を手で突き合わせる必要が出てきます。どちらの変更も、それぞれの依頼主にとっては正しいのに、同じ場所にあるというだけで、片方がもう片方の邪魔になります。
同じ週に、2人の依頼が届いたら
具体的な場面で考えてみます。月曜日に X が共有画面のURLを変えると発表し、開発者 A さんが x.toml の endpoint を直し始めました。同じ週の水曜日、サイトの運営者から「キャンペーン中は X を小さい列へ移したい」と頼まれ、開発者 B さんが同じ x.toml の primary を直し始めました。2人とも、自分の依頼だけを見て正しく作業しています。
金曜日、2人の変更を1つにまとめようとすると、同じファイルの近い行に、別々の変更が入っていることに気づきます。どちらを先に取り込むか、相手の変更を消していないかを、1行ずつ突き合わせることになります。さらにキャンペーンが終わって primary を元に戻すときには、X の URL の変更まで巻き戻さないよう、また慎重に行を選ぶ必要があります。依頼主ごとにファイルが分かれていれば、A さんは x.toml、B さんは share_config.toml を直すだけで、2人の作業は最初から最後まで一度も出会いません。
キャンペーンだけを取り消せるか、引き出しで考える
二つの変更が混ざる困りごとは、同時に作業するときだけではありません。いったん取り込んだ変更を戻す場面でも、境目が役に立ちます。次の引き出しでは、共有URLの変更と、キャンペーンの並び変更を、別々の取っ手で取り出せる形にしました。
上の引き出しには、SNSの新しいURLがあります。下の引き出しには、キャンペーン用の並び順があります。キャンペーンが終わったら、動かすのは下の取っ手だけです。上の引き出しは閉じたままなので、追従したURLを古いものへ戻す理由はありません。図の曲がった矢印は、サイトの判断だけを戻すことを表しています。
ファイルを分ければGitが必ず安全に戻してくれる、という意味ではありません。別ファイルでも一つのコミットへ混ぜれば、コミット全体を戻す操作で両方を取り消してしまえます。ファイルの境目に加えて、変更の説明とコミットのまとめ方も、判断の境目に沿わせる必要があります。引き出しが別でも、二つをひもで結んで引けば一緒に動く、ということですね。
また、同じファイルの別の行を直しただけなら、Gitが自動で取り込める場合もあります。文章上の競合が起きるかどうかと、別々の判断が同居しているかどうかは別です。自動で取り込めても、URLの変更と並びの変更を別々にレビューしたいという負担は残ります。SRPの効果を「競合がゼロになった」だけで採点しないのは、このためです。
引き出しの例で、もう一つ順番を変えてみます。キャンペーンを先に公開し、その翌日にSNSのURLが変わったとします。数日後にキャンペーンだけを終えるなら、最後に変更したURLまで戻す必要はありません。「古い状態へ戻す」ではなく、「サイトの並びだけを戻す」と依頼を言い直すと、どの取っ手を引くかが決まります。
レビューする人にも、その言い方を渡します。「並び順を元へ戻す差分」と書いてあれば、URLやパラメータに変更が混ざっていないかを重点的に見られます。逆に、変更の題が「共有ボタンを調整する」だけだと、二つの引き出しが一緒でも気づきにくくなります。責任の境目は、コードの配置だけでなく、変更を説明する言葉にも現れます。
小さなサイトでは、定義も設定も同じ日に同じ人が直すことがあります。それでも、二つの判断を分けて説明する価値は残ります。後から片方だけ再利用したいときや、別のサイトへ同じSNS仕様の修正を運びたいときに、どこまでを持っていけばよいか分かるからです。将来の担当者を増やすためだけの分割ではありません。
手元の変更でも、「この依頼だけが取り下げられたら、どの差分を戻すか」を指で追ってみてください。関係のない変更まで選び直す必要があるなら、置き場所か変更のまとめ方を見直す候補です。新しいクラスを作るより前に、既存の設定と定義へ正しく振り分けるだけで済むこともあります。
混ぜると、確かめ直す範囲が広がる
もう1つ、目に見えにくい困りごとがあります。変更したあとに確かめ直す範囲です。
並び順入りの x.toml で primary の1行だけを直したとします。直したのは1行でも、そのファイルには X の共有URLも、ロゴも、呼び名も入っています。うっかり隣の行に触れていないかを確かめるには、カード全体を見直すしかありません。一方、分けた形なら、並び順はサイトの設定ファイルにあります。手で編集する対象は設定ファイルになり、X の名札カードを変更する必要はありません。依頼主が1人のファイルなら、その依頼主の変更を、限られた場所から調べられるのです。
確かめ直す範囲が狭いことは、変更を頼まれたときの返事の速さにもつながります。サイトの運営者に「X を小さい列へ移して」と頼まれたら、見るのは設定ファイルの1行だけで済みます。共有URLの定義を直す作業とは分けて確認できます。
ここで「影響が小さい」と「確認が不要」を区別しておきます。色の設定だけを直しても、生成した設定が読み込めるか、ボタンの文字が読めるか、リンクとして押せるかは確かめます。共通の読み込み処理や表示の処理を使っているため、ファイルの境目だけで全体の正常動作までは保証できません。詳しく読み直すコードの候補を絞れることが、分割の利点です。
図の広い波紋と狭い波紋は、テスト件数を実測した面積ではありません。変更の理由から見て、重点的に調べる場所がどう変わるかの説明です。共有URLの計算は変えていないので、そのアルゴリズムを毎回読み直す必要は減ります。一方、既存の回帰テストはそのまま通します。読む範囲を小さくすることと、守ってきた確認を外すことは、別々に判断します。
考えてみる:primary を名札カードに書いたほうが、1ファイルを見るだけで済んで楽では?
読むときだけを考えると、1か所にまとまっているほうが楽に見えます。けれど、書き換えるときと確かめるときを考えると逆になります。名札カードに並び順が入っていると、並び順を変えるたびに X の決まりの行も一緒に確かめ直すことになり、X の変更が来るたびに並び順の行を壊していないかも気にすることになります。読むときの楽さのために、書くたびの手間を増やすことになるのです。どちらが多く起きるかを考えると、変更の依頼のほうが、じっくり読む回数よりずっと多いものです。









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