SRP――一つの共有先の定義は、一つの理由で変わるか
作成: / 公開: / 内容更新:
執筆:tamito0201 / 掲載・運営:プロマリ
丸い共有ボタンの裏側を掘る連載の第4回。SOLID の最初の原則 SRP を、共有先の名札カード1枚からプラグイン全体まで当てて確かめます。責任とは仕事の数ではなく、変更を頼んでくる人の数。Martin の車の修理のたとえから、実際の変更履歴を数える宿題まで、図22点で読み解きます。

こんにちは、プロマリの紫です。連載「丸いボタンの裏側」の第4回、今回から第2章に入ります。第2章では、SOLID の5つの原則を1回に1つずつ、このプラグインのコードに当てて確かめます。最初はSRPです。テーマは責任とは仕事の数ではなく、変更を頼んでくる人の数であるということ。共有先の名札カード1枚から、プラグイン全体のフォルダまで、「誰が変更を頼んでくるのか」を1つずつ数えながら読んでいきます。
点線の付いた用語は、その言葉を押すと詳しい説明が開きます。意味、身近なたとえ、この実装での使い方を順に読めます。キーボードではTabで用語へ移動し、EnterまたはSpaceで開き、Escapeで本文へ戻れます。各ページで最初に出る用語から参照できるようにしました。
この記事は連載「丸いボタンの裏側」の第4回(2.1)です。前回の1.3「ADRに残すのは結論より、捨てた案と制約」で読んだ ADR-0002 を、今回は SRP の目で読み直します。連載全体の地図は、本編5ページ目の連載の目次からどうぞ。
この回は6ページあります。1ページ目で SRP の「一つ」が何を指すのかを確かめ、2〜4ページ目で名札カードと設定ファイルとコードを数え、5ページ目で分けすぎの側とプラグイン全体を見て、6ページ目で「見つけたらどうするか」と宿題に進みます。図は22点あります。どの図も、上の問いに答えてから下の結論を読む順に作ってあります。
本題に入る前に、第2章で読む SOLID の全体像を見ておきます。SOLID は、Robert C. Martin がまとめた設計の5つの原則を、頭文字で並べた呼び名です(この頭文字の呼び名は、のちに Michael Feathers が付けたとされています)。目指しているのは、変更しやすく、変更しても壊れにくく、読んで分かりやすいコードです。
| 頭文字 | 原則 | ひとことで言うと | この連載の回 |
|---|---|---|---|
| S | SRP(単一責任の原則) | 1つのまとまりに、変更を頼んでくる人(役割)は1つだけにする | 2.1(この回) |
| O | OCP(開放閉鎖の原則) | 機能を足すとき、今動いているコードを書き換えずに済むようにする | 2.2 |
| L | LSP(リスコフの置換原則) | 同じ約束を名乗るものは、取り替えても使う側が困らないようにする | 2.3 |
| I | ISP(インターフェース分離の原則) | 使う側に、使わない機能まで押し付けない | 2.4 |
| D | DIP(依存性逆転の原則) | 大事な判断を、具体的な道具ではなく約束(抽象)に頼らせる | 2.5 |
5つに共通するねらいは、2つにまとめられます。一緒に変わるものは近くに集めること(これを「凝集度を高める」と言います)。別々に変わるもの同士のつながりは弱くしておくこと(これを「結合度を下げる」と言います)。そうしておけば、1つの変更の影響が、関係のない場所まで広がりにくくなります。
ただし、SOLID はどんな場面でも守れば正解、という規則ではありません。守ることにこだわりすぎると、ファイルや部品が増えすぎて、かえって読みにくくなったり、作る手間が増えたりします。この章では、5つの原則を1つずつ、この共有ボタンのコードに当てて、「どこで効いているのか」と同時に「どこでは使わないのか」も確かめていきます。
「一つの責任」は、一つの仕事のことではない
SRPは、日本語では「単一責任の原則」と訳されます。この訳を読むと、多くの人がこう受け取ります。1つの関数は1つのことだけをする。1つのクラスは1つの処理だけを持つ。だから、細かく刻めば刻むほど良い。
けれど、この原則を広めたRobert C. Martinは、2014年に書いた記事で、この受け取り方をはっきり正しています。記事は「SRP は、1つのモジュールが変わる理由は1つだけであるべきだ、と言っている」という確認から始まり、すぐに「では、変わる理由とは何か」と問い直します。そして答えとして、Martin は「この原則は、人についての原則だ(This principle is about people.)」と書いています。1つのまとまりに、変更を頼んでくる人が1人だけになっているか。それが SRP の問いです。
図の右側を見てください。x.toml に変更を頼むのは X(SNS各社)だけ、share_config.toml に変更を頼むのはサイトの運営者だけです。どちらのファイルにも項目は何行もありますが、依頼主は1人ずつです。行数が多いか少ないかは、この問いには関係がありません。この回では、この「依頼主の数」を手がかりに、プラグインのファイルを1つずつ数えていきます。
なぜ「人」で数えるのか――頼んでいないところが壊れる
変わる理由を、わざわざ「人」で数えるのはなぜでしょうか。Martin は、記事の中で車の修理にたとえています。窓が動かなくなったので、修理を頼みました。翌日、直ったと連絡があって取りに行くと、窓は確かに動きます。ところが、エンジンがかかりません。その修理工場には、もう二度と頼まないでしょう。
困るのは、頼んだところが直らないことより、頼んでいないところが壊れることです。頼んだ人は、自分の頼みとは関係のない場所が壊れるとは思っていません。だから、壊れたときの驚きも不信も大きくなります。
共有ボタンでも同じことが起きえます。サイトの運営者に「ボタンの色を少し明るくしたい」と頼まれて直したら、翌日から X の共有画面が開かなくなった。もし色と共有URLが同じファイルの同じ場所に書かれていたら、色を直す作業の途中で、URL の行をうっかり壊すことはありえます。色を頼んだ人も、URL を決めた X も、そんな変更を頼んではいません。変わる理由の違うものを1か所に置かないのは、頼んでいない人の持ち物を壊さないためです。
Martin の例:1つのクラスに、3人の依頼主
Martin は、もう1つ、会社の例も挙げています。社員を表す Employee というクラスに、3つのメソッドがあるとします。
public class Employee {
public Money calculatePay();
public void save();
public String reportHours();
}calculatePay は、社員の契約や勤務時間から給与を計算します。save は、社員のデータを会社のデータベースへ保存します。reportHours は、監査の担当者が読む勤務時間の報告を作ります。では、それぞれの「こう動くべき」を決めるのは誰でしょうか。給与の計算方法を決めるのは、お金の責任者である CFO です。保存の仕組みを決めるのは、技術の責任者である CTO です。報告の形を決めるのは、業務の責任者である COO です。
1つのクラスに、3人の依頼主がいます。CFO の頼みで給与の計算を直したとき、うっかり報告の形まで変えてしまったら、困るのは頼んでもいない COO です。Martin は、変更の依頼が「1つの狭く定まった業務の役割を担う、ひとまとまりの人たち」からだけ来るようにしたい、と書いています。1人の人というより、1つの役割の人たち、という意味です。
責任とは、変更を頼んでくる人のこと
変更を頼んでくる人を、この記事では依頼主と呼びます。では、共有ボタンのコードには、どんな依頼主がいるでしょうか。数えてみると、4者に分かれました。
SNS各社は、共有画面のURLやロゴ、呼び名を変えます。サイトの運営者は、どのボタンを大きく出すか、どんな言葉で出すかを変えたくなります。ブラウザと標準は、コピーの仕組みや端末の共有画面の呼び出し方を変えます。保守する開発者は、検査を足したり、書き方を整えたりします。4者は、変えたい理由も、変えたい時期も、ばらばらです。
| 依頼主 | 変わるきっかけの例 | 届け先 |
|---|---|---|
| SNS各社 | 共有画面のURL・ロゴ・呼び名が変わった | destinations/<key>.toml |
| サイトの運営者 | ボタンの並び・言い回し・色を変えたい | config/share_config.toml |
| ブラウザと標準 | コピーや共有画面の仕組みが変わった | web/src/infrastructure/ |
| 保守する開発者 | 検査を足したい・書き方を整えたい | web/test/・tools/ |
このプラグインでは、4者の依頼がそれぞれ別の場所へ届くように置き場所を分けています。表の「届け先」の列が、それぞれの依頼の届け先です。どの届け先にも、依頼主は1人だけです。
考えてみる:同じ人が、SNSの担当とサイトの運営を兼ねていたら、依頼主は1人になるの?
依頼主は、人の数ではなく、役割の数で数えます。同じ人が X の仕様変更に追従する作業と、サイトのボタンの並びを変える作業を両方しても、その2つの変更は別々の理由で、別々の時期にやって来ます。ファイルの側から見れば、2つの別の都合が届いていることに変わりはありません。Martin の記事でも、変更の出どころは1人の人というより、「1つの狭く定まった業務の役割を担う、ひとまとまりの人たち」と説明されています。











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