クリーンアーキテクチャの運用について考えている(2019)
https://1.bp.blogspot.com/-Sz-ybePDzbU/XTPocsOWPAI/AAAAAAABTzE/VlWGCsfKzFMg3ikxC8MaXb-4J1wbRCgmQCLcBGAs/s400/monogatari_inaba_shirousagi.png
2020-10-01 追記: ここの内容は古いのでそのうち再編成されます。
実装に対する境界線を引くことについてはわりとうまくいったように感じている。
・・・が、一方でファイル数と抽象化のために必要な記述量が増えてしまっているのが悩み。
わかりやすいところでいうと例えば、「会社やプロジェクトから自分がいなくなったときにクリーンな状態を維持できるか?」は結構疑問があって、チームの意識形成みたいなところを頑張らないといけないのかなぁと思っているところ。
一般的な話としてよくありがちなのがこういうのをリードする人がいなくなると、だいたい崩壊するかリセットがかかる。
そんなこんなでぼちぼちで、見えてきたメリットや課題点を上げてみる。
メリット
実装の境界線ができるので、配置をどこにすればいいか整理される
「MVC2」であるようなどこになにを書いたらいいのかっていうガイドラインが出来るので基本的に困らない。 もし困るんだとしたら複数のそうにまたがるビジネスロジックがまぜこぜになってる可能性が高い。
現状では MVC2 っぽいものを採用しているのでもう一歩踏み込みたい。
実装の境界で依存が断ち切られるのでユニットテストがしやすいコードになっていく
モックすれば一緒でしょというのはもちろんあるが、何でもかんでもモックにすればいいというものでもないし、常に迷いなく秘孔をつけるような設計に保てるのはメリット。
適切に運用される限り外部依存の変化に強いアプリケーションになる
EOLや非互換の大型アップデートされてもアダプタが interface を満たす限り可換になる
4層の外部ライブラリの層をなんとかすれば基本的には他の層には全く影響が出ないのでメンテしやすい
モノリス でも マイクロサービス でも使える
分割の方向が縦か横かと言う話なので基本的には競合しない。
課題点
クリーンアーキテクチャに強い人がいないと崩壊するかもしれないと言う予感が否めない
そもそも解決したい課題はクリーンアーキテクチャにすることじゃなくて、コンポーネントの依存を薄くしてテスタブルにすることだからここ間違っちゃいけないんだよね。
Strict に運用すると記載量やファイル数が多くなるので、受け入れがたい気持ちがでてきがち
根気よく説得するか、運用ルールを緩めに設定するなどが必要。
細かなライブラリ (時間操作や文字列操作など) の使い勝手が悪くなる
ルール通り Frameworks & Drivers に押し込むと依存が切れるのはいいが使い勝手が犠牲になる。
チーム開発なら合意に基づいて、例外として取り扱うのは運用として有り。
初期化するときのコードが長くなる
DIコンテナを使うことでマシにはなるが、DIコンテナへの依存はありなのかと考えている部分もある。
オーバーヘッドってどんなもんだろって感じ
new する量が増えてるのでパフォーマンスへの影響って0ではないと思っている。(しかし未計測)
「外部を可換にするっていっても実際に依存するDB/APIはそれぞれ1種類しかないじゃん」と言う現実
依存する先が何らかのクライアントライブラリになっていれば、そこでモックに差し替えられるから interface とか class で可換にする必要がないよねって話。
逆を言うとモックとかで処理を上書きできないような言語向けの設計なのかなぁとも思っている
一方で直接クライアントライブラリにガッツリ依存するのもいいとは言い切れない
究極、「ビジネスロジックを遂行することが目的」なので「どのライブラリをつかうか?」みたいなコンテキスト上「重要でない詳細」に区分されるものは、意思決定を後回しもしくは可換にできることが良い設計。
対策
雛形生成君を用意する
あまり現実的じゃない選択肢だと考えている。
こういう仕組みは使わないひとは使わないから。
これで行くならしくみを圧倒的に便利にするか、あるいは政治力を発揮するかの2択。(政治とは(とは))
3層と4層をマージすることを許容する。
Interface & Adapters と Frameworks & Drivers の層を混ぜることを許容する。これによりclass と interface の記載量をへらすことができる。
可換にする必要がない機構やモック可能な処理系だとやり方としてはありかなと思っている。1層と2層も必要に応じて分割する感じなのでそれと似た感じとみなすイメージ。
一部外部ライブラリを合意に基づいてどの層でも使っていいようにする
楽にはなるが、許容したものが大きく変化したり置き換える必要に迫られたら辛くなる。
よほど慎重に運用するなら選択肢としては有りかなぁとおもう。
といろいろあるけどこの辺の考え方とか感覚とかをアレして、もうちょっとチーム内で聞いて回ってみたいと思っている。