【Clean Architecture座談会】第4回
mohikanzというエンジニアコミュニティで、Clean Architectureを読んだ人で集まってオンライン座談会を始めました。
前回までのレポートはこちらです。
今回は第4回。21章「叫ぶアーキテクチャ」と22章「クリーンアーキテクチャ」について白熱した議論をしました。
正直グラレコがあまり録れなくて後から見ると心残りです。色んなためになる話をしていたと思うので、可能な限り振り返っていきたいと思います。
21章 叫ぶアーキテクチャ
参加者全員がRuby on Rails(以後Rails)でアプリを作った経験があったため、Railsだとこれを実現していくのは大変だよね、という話が印象的です。
特に業務でRailsを使っている方が「これをやるとRailsの良い所を何も活かせなくなる」というくらいに捉えられていました。
実際、RailsがWebフレームワークの中でもかなり「予め敷かれたRail」に従わせる性格が強いので、Clean Architecture的な考えを後から持ち込むのにはかなり難しいフレームワークなのではないか、という話になりました。
自分は現在Node.jsのフレームワークであるexpressを使って業務のコードをClean Architectureで書けないか格闘中ですが、Railsに比べるとかなり叫ぶアーキテクチャにはなっていると思います。また、NestJSがかなり良いというオススメを受けています。
22章クリーンアーキテクチャ
皆でタイトル回収回だね! と盛り上がったものの、まさかそこから3時間の議論になるとは誰も思っていなかった。
グラレコも4枚に分かれたので、それぞれ振り返っていきます。
全体通して、Entitiesに何の情報を含めるべきなのか? という問いが主題にあったように思います。
クリーンアーキテクチャ1
最初話題になったのは、「最重要ビジネスルール」としての「User」オブジェクトは、データプロパティとして「パスワード」なり「認証トークン」を持っているべきかどうか? でした。
OAuthを行う事に専念するコンポーネントであればそれらは主要な関心事として扱われるべきであり必要、ショッピング用のコンポーネントであればそれらが無くとも購入やその他の行為を行う事はできるのでむしろ邪魔、という分け方が正しそうだ、という事に落ち着きました。
そして確かにそれ自体は納得できるけど、実際に同じユーザーというものを扱う中でそこまで分割するのか? という事で、「ドメイン駆動設計入門」で紹介されていた凝集度を計る尺度であるLCOM(Lack of Cohesion in Methods)を紹介するなどしました。
クリーンアーキテクチャ2
DDDにも通じますが、エンティティオブジェクトはふるまいを持っていて欲しいのに、データ構造以外のふるまいはユースケースに持っていかれてしまいがちです。具体的に何をエンティティに書けばよいのだろうか。
例えば「(ユーザーは何らかの属性を持っていて)自分と同じ属性のユーザーを探す」というようなメソッドを持っているのではないか? という話が出たのですが、ユースケースとの違いが微妙です。
エンティティが持つ方が良さそうなふるまいについては来週までにぼんやり考えてみよう、という事になりました。
クリーンアーキテクチャ3
「境界線を超えるデータ」という項で「DBの行やエンティティオブジェクトのまま境界線を超えるな」という話があり、直近で私が設計したコードにマサカリを投げられた感がありました。
DBモデルを直接DB層以外に渡すのは当然NGなのですが、そのための型がエンティティオブジェクトであると考えていた(DDDの文脈で言うと、DBの値を変換してドメインオブジェクトを作成するのはリポジトリーの責務)ので、ここは大いに混乱しました。
実際次の項「典型的なシナリオ」で紹介されていたクラス図を見ると、境界線をまたぐ時には専用のデータインターフェースを作っていたように見えますが、そこまでしなければならないのか? というのが正直な感想です。一旦はエンティティオブジェクトのままでいいんじゃないかな...
クリーンアーキテクチャ4
まとめの部分で「ルールを守ることは簡単」と書いてあって自分は大いに「ウソつけ!」とコメントしたのですが、「1つ1つは簡単だけど、全部守るのは大変だ」というコメントが出てきたので納得しています。
全体通して
Entitiesに持たせるべきふるまいが分かっていなかった事と、エンティティオブジェクトのまま境界を超えるのがNGだった事が自分にとって驚きでした。
後者に関しては一旦原則の方を保留にしようかなと思っていますが、前者についてはドメイン駆動設計やユースケース駆動開発などを参考にしてあるべき姿を引き続き検討していきたいと思います。