方針
- Railsに合う形でClean Architectureを導入(あるあるのFat Controller、Fat Modelと対応する形で表記)
- 対Fat Controller
- Usecase層導入(Serviceという名前はどのサービスを指すかわからなくなるので使わない。)
- 対Fat Model
- Modelの分離
- UsecaseのアクターごとのModelを作成する。
- 必要に応じてcomposed_ofを利用したValue Objectの導入
- Usecaseの実装をModelに実装しない(Modelには一般的なルールを実装する。一部のUsecaseに処理が存在するという理由だけでModelに移動しない。一部の重複ならそれはたぶん共通Usecase)
- Modelの分離
- 対Fat Controller
具体
controllerのイメージ
|
|
usecaseのイメージ
|
|
modelのイメージ(たぶんこんな感じ)
|
|
言葉の定義
- 単一責任の定義: 一つのアクターに対して責任を負う (Uncle Bobの定義を利用)
私見
- Fat Controllerに関して
- リソースあるいはリソース群の作成、更新、参照は特定のアクターの要求を満たすためにほぼ同時に実装の変更が入ることが多いのでRailsのControllerが単一責任を破っているとまでは思わない (削除は変更が連動して発生しないので少し特殊な気はする)。
- Controller内でinner class使えばそこまで見通しは悪くなかったのでは?結局Controller内のメソッドのみで書こうとするのが問題の本質では?(掘り下げ続けると教育が云々とかまでたどり着くような…)
- Fat Modelに関して
- そもそもUsecaseに書くべきことがModelにあふれているのでは?2,3箇所しか出てない共通ロジックならばおそらくそれは共通Usecaseとして表現されてしかるべきものでは?(Usecaseのコンポジションで表現されるべきものなのでは?)1Usecaseでしか使われてないメソッドがモデルにあるとしたらどう考えても過剰な実装では?(何かしらの原理主義的な感じが…)
- RailsのModelがどうのこうのというよりは単一責任の原則を守らず突き進んでいるから発生するのでは?
- RailsのModelに関して
- Entity, Gateway, Infra(といえば良いのか?)がくっついた立ち位置の認識。
- アクターごとにModelを分離すれば単一責任は守られる
- トランザクションに関して
- 通常Usecaseが境界になるのでUsecase内で行う感じで、1Usecase1トランザクションかなと。