kazu22002の技術覚書

PHPer, Golang, AWS エンジニアの日々

clean architectureを1年間やってみた感想

clean architectureとはシステムのアーキテクチャのひとつの考え方です。

最近ではよく見かけるようになり、開発に取り入れたプロジェクトも多くなっていると思います。

参加したプロジェクトでクリーンアーキテクチャを採用していたため知見や感想を書いてみます。

ただし個人的に理解できていない部分も多く、実践しながら模索している最中でもあります。

clean architectureとは

クリーンアーキテクチャドメイン駆動設計の考え方のひとつです。

下図がよく見かける図になると思います。

f:id:kazu22002:20190923222050j:plain

blog.cleancoder.com

本家の内容を読んでみるといいと思います。

アーキテクチャの考え方としては

  • フレームワークに依存しない
  • テスト可能
  • UIに依存しない
  • データベースに依存しない
  • 外部機能から独立している

この考え方を単一の概念に無理なく統合する試みが図に表されているみたいです。

依存しないよう作れる仕組みはありがたい話だが、なぜこの考えが良いのか。いままでのシステムはどう依存して作られていたのかを一度考えるといいと思います。

詳しく書かれている記事やサンプルも結構あるので、参考にしながら理解してみてください。(僕は詳しく説明できません)

考え方やサンプルを真似して作成した時期は2018年3月ごろのため、いまはもっと多く記事が出ています。

※ 参考にしたページ

qiita.com

postd.cc

やってみてどうなったか

この考え方を理解していた人が少なく、まず動くものを作ることが前提になっていたためMVCに近い内容になってしまったと思います。

理想としてはユースケースで様々なロジックを作り、データについてはミドルウェアに依存しないで動くのがいいと思っています。

コントローラーも呼び出しの種類を複数作成することにより、UI依存をなくせると思っています。

ただし長期的にプロジェクトを考えればいい仕組みだと思いますが、短期的にみると依存関係で書いた方が早く、コードを書く人間からすると理解しやすい状態になります。

クリーンアーキテクチャで書く際にはまずインターフェースを定義し、ロジック部分を書いていきます。

ファイル数が増え、ソースコード量もかなり多く書くことが多くなりました。

MVCで慣れていると、簡単にモデル、ビュー、コントローラーに書けばいいため理解としては早いと思います。一般的にはモデルが肥大化するとあるように、コードの肥大化に悩まされたことは多々あります。ですが、簡単であったと実感はしています。

簡単なプロジェクトであれば、クリーンアーキテクチャを導入して複雑にする必要はないのではないかと思っています。

ただプロジェクトの寿命がよめる人はいないと思うので、万全を期す意味で取り入れながらプロジェクトを作るのはお勧めできます。

しっかりと考え方を理解すれば、ミドルウェアなどの変更に強いシステムになることは実感できました。またレイヤーごとのテストもプロジェクトに浸透させることができれば、安定したシステムも目指せると思います。

その他に製造過程で悩んだのは、リポジトリの記述であり、モデルの考え方があるためデータベースごとにファイルを作成していました。

では複数テーブルの場合にどうすればいいの?という議題で話し合いがされ、ユースケースにあったリポジトリのファイルを作成すればいいのか、データベースのテーブルを元に作成したファイルに追記すればいいのか。と話がされプロジェクトとしてはデータベースのテーブルごとのファイルが作成され、必要な内容をメインのテーブルのファイルに書いた結果となってしまった。

MVCの流れで書くとリポジトリはテーブル単位で作ってしまうため戸惑います。どういうデータに対する処理かでファイルを分けてよかったと思っています。DRYの原則からは外れますが、複数書くこともありだと思います。

失敗したと感じること

データの取得や登録の部分とコントローラー部がうまくなかったと思う部分です。

インターフェースを定義して、依存関係を気にしないようデータを取得したいのですが、今回はデータベースを使用するよう書いていたのでデータベースに依存する書き方をいくつかしました。後述しますが、トランザクション周りです。

ファイル登録とデータ登録を同じ機能でしていたため、依存した書き方をしています。動作上は問題ないのでこのまま動かし続けますが理念としてどう書いたら実現できるのか模索中です。

あとはクリーンアーキテクチャついて、プロジェクト参加者の理解度を合わせる必要があったと思っています。

問題点がでれば解決していましたが、なぜこの書き方を推奨するのかもっと会話をしながらやっておけばよかったと思っています。

最初からうまくいくとは思ってませんが、いい案が思いついた時に共有できなかったため個々で別々の書き方になってしまい修正できない状態にしてしまいました。

よかったと感じること

正直なところ、ないです。

これから運用をし続ける中で感じることだと思っており、開発が終えた段階で感じた利点はないです。

テストをいままで書いてこなかった人が書くようになったのは利点だったかな。

プロジェクトを終わらせるのに必死だったのと、golangの経験が浅く、データベースのoracleに悩まされるほうが多く今回の設計が良かったのかわかりません。

インポートツールを作る際に同じロジックを使用できたことは、今思えば理想的な形でのアーキテクチャになっていたと感じますが、golangの書き方でうまくなかったのか別プロジェクトから呼び出したため型を合わせるのに苦労しあまりメリットを感じれなかったことはあります。

同じプロジェクト内であれば、かなり簡単にロジックの共有ができるのは事実です。

ビジネスロジックをしっかりと分離する考え方にできることかな。ドメイン駆動設計が実践できたことが個人的な成長につながったことぐらいです。

未解決な内容

トランザクションについて悩んでいます。言語はgolangで書きました。

いいやり方がある場合、ぜひ教えて欲しいです。

現在はリポジトリ内で完結させるように記述していますが、リポジトリファイルを複数にした場合にうまい書き方で悩んでいます。

トランザクション = 整合性 と思っているため、ユースケースで書くのがいいと思っていますが、リポジトリに依存する書き方になってしまいうまくかけていない状態です。

一応の解決内容は書いてみましたが、まだ実際に動いたプロジェクトでないため模索中です。

最近記事がまた多くなってきたので、いろいろ参考にさせてもらいながらやっていきたいと思います。

いまさらドメイン駆動設計を読んでいるところのためもっと改善できるかもしれないです。

エリック・エヴァンスのドメイン駆動設計 (IT Architects’Archive ソフトウェア開発の実践)

エリック・エヴァンスのドメイン駆動設計 (IT Architects’Archive ソフトウェア開発の実践)