SOLIDの勉強がてら、RAILSでの使い方についてとりとめもなく考えてみる。
SOLIDそのものについては、クリーンアーキテクチャ の7-10章をそのままベースにしてるので、派閥争いで「SRP原則はこんなんじゃねぇよ!」とかが実はあるのかもしれないけど、その辺りは後回し。
単一責任の原則(SRP: Single Responsibility Principle)
SRPの良く聞く説明は、「モジュールを変更する理由は一つだけでああるべきである」とういうものだけど、クリーンアーキテクチャによると正確には**「モジュールはたったひとつのアクターに対して責務を負うべきである」**なのだという。
大雑把に例えると
**「同じシステムであっても、社長アクターが使用する機能は、一般社員アクターが使用する機能と、コードレベルで別れているべきである」**って感じだろうか。
こうしておけば、社長起因でコードが変更された場合に、社員が使用する機能が影響を受ける事は無い。
Railsでどう考えるか
Railsでアクターというと、どの単位になるんだろう。
シンプルに考えると、一つの画面は同じ人物が使うのだから、config/routes.rb
のresources
で指定されたあるルートは、同じアクターによって使用されるとしても良いだろう。
つまり、ある〇〇_controller.rb
は、同一アクターが使用するものだと考える。なので、Controllerまでは、割と勝手にSRPに沿って分かれていると言える。
問題になるのは例えば「社員一覧」の様な、社長でも一般社員でも使えるべきページについて考える時で、このページを社長と一般社員でわけるのは流石に無意味過ぎる。
ここは「アクターは概念なので、同じ主体が複数持つ事が出来る」と考えれば良いだろう。
「社員一覧」ページは社長でも社員でも見えるけど、その時のアクターは「全社員」という、別のアクターなのだ。
「全社員」は抽象で、「社長」や「一般社員」はその具象なので、別々のアクターとして扱える、という事かもしれない。
ここから、**「そのresourcesを利用するアクターは何者なのか、はっきり明記する」**は、やっておいても良いと言えるかもしれない。
コード分割云々以前の、そのシステムが誰に対するもので、どう使われるべきなのかを理解する手助けになりそう。
もっと前の、設計の時点でちゃんとアクターの洗い出ししておけっていう話かもしれないけど、そんなに綺麗に作られている事、あんまり無いだろうし、あとからでもやっておきたい。
Controllerのコード自体は、本来のSkinny Controller
を目指していれば、そうそうおかしな事にはならないのでは。
Modelはどうだろう。
RailsのModelは、みんなが苦しんでる通りに、多くの責任を背負う場所になっているんだから、さぞかし分割し甲斐があるのでは?
とは思うものの、いわゆるファット・モデルの分割については、過去に喧々諤々の議論があり、まだベストプラクティスは出てない状態らしい。
(参考)
俺が悪かった。素直に間違いを認めるから、もうサービスクラスとか作るのは止めてくれ
Ruby on Railsの正体と向き合い方 / What is Ruby on Rails and how to deal with it?
個人的には、大規模になる事が分かってるんだったら出来る限り早く分割したい。個人的な趣味嗜好の問題で、責任いっぱいのクラスを見てると苦しくなるし、個人的な能力の限界で、200行を超えるクラスは読めないからだ。
特に、ActiveRecordが根本に存在しているModelは、RDBのデータ構造と完全に結合していて、そのデータ構造で賄える範囲でしかシンプルなコードが書けないわけで、複数テーブルをまたいだコマンド系の処理は、そもそものrails wayの想定の範囲外。
一刻も早く分割しないと、後々の保守で地獄を見る羽目に陥るんじゃないかと思う。
分割した場合でも「ファット・モデルは目指すべきものである」というrails wayから外れる事になるけど、こういった「Modelに複数ユースケースが紛れ込んでる」ケース自体が、もっと根本から道を外れているわけだし、そういう場合の分割は許されるべきというか、積極的にやらないと、もう線路に戻れなくなるんじゃないだろうか。
そして、ユースケースが複数になるという事は、アクターが複数になっている事も多いだろう。
SRPを考えても、やはり大規模になったモデルは分割(なり、対処)を考えた方が良いと思う。
callbackもvalidationも分かれる事になるんで、物凄い茨の道なんだろうけど。
(参照)
サービスクラスについては僕も悪かったと思っているけど、それでもCQSは実現したいんだ
Railsプロジェクトにサービスクラスを導入して4ヶ月たったので振り返る
Railsのファットモデル問題に対処する前に読んでほしい記事
HelperやConcernは正直具体的にどう考えて良いのかわからない。
けど、アクターベースのSRPで考えると、明らかに火薬庫なので、取り扱い注意になるのは間違いない。
各自自助努力で、出来る限り凝集性を保って頑張るべき、というしかない気がする。
オープン・クローズド原則以降は、暇な時に次考えます。
Qiita文化が良く分からないんだけど、許可取らずに勝手に参考リンクとか貼って良かったものなんだろうか…