はてブで単一責任の原則(Single responsibility principle)について、もう一度考えるといふ記事を見掛けて、なんとなく懐かしい気持ちになった。久し振りにこの言葉を見たなって。
「一つのモノに一つの責任 (役割) を」といふモットーは、初めて聞いた時にはすごくもっともらしく聞こえるんだけど、いろいろ考へてくと結局「責任が一つであるとはどういふことなのか?」「といふか、責任って一つとか二つとか数へられるものなのか?」といふ疑念を抱くよね。俺も昔さう思ひました。
で、この菅野さんの記事では「責任が一つであるとは、一人の利用者 (アクター) に対してだけ責務を果たすこと」といふ話をしてゐる。その理解はたぶんそんなに間違ってはゐないと思ふ。ブコメに「作者の人そこまで考えてないと思うよ」とかいふコメントもあったけれども、菅野さんの記事が信用できないと思ふんならボブ本人による記事を見たらいい。
However, as you think about this principle, remember that the reasons for change are people. It is people who request changes. (強調は原文のまま)
ってちゃんと書いてある。
単一責任原則の紛らはしいところは、「一つのクラスに一つの責任を」といふフレーズが独り歩きしちゃったことがあるのかなとも思った。クラスといふ単位にこだはりすぎてはいけないんだ。さっきのボブをぢさんの記事をもう一度引くと、
The Single Responsibility Principle (SRP) states that each software module should have one and only one reason to change.
とある。クラスの話はしてない。モジュールの話をしてる。一つのクラスが一つのモジュールとなることもあるかもしれないが、常にさうだといふわけではない。複数のクラスが一つのモジュールになることの方が多いだらう。その場合、一つ一つのクラスについて単一責任を考へてもしゃうがない。
しかし、だ。結局のところ、ある機能 (といふか要件) の出処が同じアクターなのか違ふアクターなのかって、さう簡単にわかるものなのだらうか? ボブの記事に出てくる「CFO にとっての社員と COO にとっての社員と CTO にとっての社員は別だよね」といふ話は何となくそれらしく感じられるが、菅野さんの記事に出てくる管理者ユーザーと一般ユーザーの共通部分としての共通ユーザーはかなり人工物っぽさがある。単一責任原則が常に成り立つことを正当化するために無理やり架空のアクターを捏造してる雰囲気ありません?
例へばあるプログラミング言語のインタープリターを作るとする。いはゆる REPL といふやつだ。この場合、R の部分と E の部分と P の部分 (つまり、コマンドを読み込む部分と実行する部分と結果を出力する部分) はそれぞれ別々のモジュールにすべきだらうなといふことはまあ直観的に分かる。が、それは三つの部分に異なるアクターがゐるからなんだらうか? ややもすると「言語設計者といふ一人のアクターがゐるだけでは?」といふ結論で満足して終はってしまはないだらうか?
アクターといふ概念は、といふかある部分に対応するアクターが同じなのか別なのかといふ観念は、設計時に最初から解ってるものといふよりも、むしろドメインに対する理解が進んだ後から判ってくるものではなからうか。何もかも最初からうまく設計できるなんてことがないのはみんな分かってるでせう?
……とか考へると、単一責任原則が適用できるのは割と限られた状況だと思へてくる。責任がどのアクターに向いてるものなのかがはっきりしてる状況なら、それに従ってそのモジュールを明確化できるだらう。さうでないのなら、単一責任原則はうまく働いてくれさうにない。
一方俺はむしろ、ボブの記事に引用されてたパーナス論文の一節に大きなヒントを感じる。
We propose instead that one begins with a list of difficult design decisions or design decisions which are likely to change. Each module is then designed to hide such a decision from the others.
アクターとか責任とかを云々するよりも、「変更され得る design decisions (設計上の選択) を分離する」といふ一言の方が分かりやすくないだらうか。アクターってその機能を使ふ人つまりその機能の外側にゐる人なので、その機能からは離れてるといふかちょっと遠いんだよね。それよりも、機能そのものについて考へを巡らせた方が捗る気がする。
設計に関して選択を迫られることはよくあると思ふんですよ。ここはかういふ設計にすべきだろうか、あるいはああいふ設計の方が良いだらうか——ドメインが複雑なとき、どんな設計にするのが良いのかその場で見当が付かないこともある。それでも、我々はどれか一つの設計を選んで実装しなくてはいけない。それはつまり、今選ばなかった設計を将来選び直すかもしれないといふことでもある。
あるいは、要件や仕様が不安定な場合もある。実験的な機能を実装した後、評判次第で仕様を変へたり変へなかったり。
さういふ「変更され得る部分」を実際に変更しようとするときに毎回システム全体をいぢくらないとダメなんてことになったらやってられんわけで、だからなるべく最小限の手直しで変更が可能となるやうに分けておくって話。さう考へると何をどう分ければいいか何となく分かってくる気がしませんかさうですか