🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
API

APIはApplication Programming Interfaceの略です。APIはプログラムにリクエストされるサービスがどのように動作するかを、デベロッパーが定めたものです。

Q&A

解決済

2回答

925閲覧

Clean Architectureには本当にあの4重丸なのですか

impepc

総合スコア86

API

APIはApplication Programming Interfaceの略です。APIはプログラムにリクエストされるサービスがどのように動作するかを、デベロッパーが定めたものです。

0グッド

1クリップ

投稿2020/01/03 11:17

最近、Clean Architectureを勉強しようと図書館で借りて読んで見ました。
メモを取りながらだったのですが、blogなどのネットの情報と比較してみると違和感を感じました。

私のClean Architectureの理解は下記の通りです。

Clean Architectureの主眼は依存性の問題の解決だと思っています。大事なロジックやデータを外部のDBやUIの変更から守るのかだと考えています。

あの4重丸はそのベストプラクティスのような位置づけだと思っています。しかし、様々なブログで書かれるClean Architectureはあの4重丸を前提に書かれています。4重丸を前提に書かれるのではなく、実際に記事にするのであれば設計や実装で発生した依存性の問題をどう解決したのかが見たいのですが、あの4重丸をどう実装したのかの話ばかりな気がします。

私の懐具合もあり、正直なところ図書館で借りてメモした内容を前提で書きますが、理解不足についてご指摘頂ければと思います。

要点:
Clean Architectureは作り方の指針である。
主な視点は依存性の問題。何が何に依存するかによって変更や修正によって発生する影響を最低限に留め、変更に強く拡張しやすいシステムを作るのが目的である。(メリットとしては開発の序盤での決定事項を先送りにし、理想の形が具体的に見えたところでの仕様決定しても問題ないようにするなど)
上記の補足として

  • 依存性の問題は依存元の変更により依存している側に変更が発生することである。
  • 重要なものは変更すべきではない。むしろ、変更依存元になるべき。フレームワークや言語などはバージョンアップなどの変更が常に発生する可能性があるので依存は低いほうが望ましい。それらは依存関係のチェーンの元から遠いところにあるべき(フレームワークなどのバージョンアップなどにより重要なものに変更が入るのを防ぐ)
  • ドメイン(そのプログラムが担当する部分)以外からデータをやり取りをするときは依存先が定義したインターフェイス(データの型のみ。実装は何もしない)で行う。これはドメインの依存性を最低限に抑えるため。

以下、上記の補足事項

色んなブログでClean Architectureを実装してみた系の記事ではClean Architectureをあの4重丸を主眼においており、「重厚なものである」と書かれています。
私の理解はClean Architectureは「何が何に依存することで良い設計になるか」なので別に不要なら層を飛ばしてしまえば良いと思っています(そういうパターンはあまり見当たりませんが)。
ついでにいうと、あの4重丸のうちフレームワークを使ってもいいのは外から2番目の丸までだと思っています。Entitiesは会社の重要データのルールなので、フレームワークに依存してはいけないでしょうし、ユースケースもセッションの保持もフレームワークに依存してはいけないでしょう。

一方で、システムによってはEntitiesがないものもあるでしょう(ツール類など(メール送信システムやデータを参照するだけのシステムとか))。
あの4重丸の図を前提に無理矢理作ってしまうと、このシステムのEntitiesってなに?となると思います。
また複数画面ある場合もあの4重丸を通らなければならないのかという疑問にもなると思います。

あの図は

  • システムにはUseCase(アプリケーション)があり、それがベースだが、それ以上にそれは会社のデータのルールに従う必要があること(Entities)
  • デバイスやUIなどではデータなどがユースケースの実行に達しない場合があり、それはコントローラーで吸収する
  • 画面もあるデータはプレゼンターで定義するが、どう表示するかはUIで作成する。そのときはフレームワークを使っても良い

示しているという考えです。ついでに言うと

  • DBとUIが離れているので一度中を通らなければいけないと考えてしまうが、自分の中で完結しているならばコントローラー内だけで一時的にデータを貯めるのはOK。事実、MVCもInterfaceに含まれると書いてある)
  • UseCaseの中でトランザクションを切るとしても、それはインターフェースを通してであり、UseCase自体は何のフレームワークを使っているかは知るべきではない
  • 永続化などを行うときはAbstract Factoryのような依存関係の逆転を使い、制御の流れとは違う構造になるようにしてDBにUseCaseが依存しないようにする

を示している図だと思っています。

まとまっている感じはないかもしれませんが以上が私の理解です。
とにかく、Clean Architectureは依存性の問題であること。
あの図から言えるのは、依存すべき先はUseCase(そしてEntities)である。
が私の考えです。わざわざ、Entitiesにならないようなものにまで無理くりEntitiesにしなくてもよいと思います。そのときはUseCaseが輪の中心にくるのだと思います(UseCaseのないソフトはありえないと思っているので)
そして言語やフレームワーク、DBなどのミドルウェアはできるだけ円の外側(依存する側)にすることだと考えます。

私は原理主義者ではありません。ただ、私の理解と多くのブログに書かれている内容に差異を感じています。
間違いがあればご指摘ください。

PS1a. これを書きながらSIer論の事もふと深まりました。私の述べるClean Architectureならば、ビジネスロジックに従って製品のカスタマイズ中心のSIもClean Architectureなのではないのかなぁと

PS2. タグは適当です。アーキテクチャなどはなかったので・・・

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

y_waiwai

2020/01/03 11:25

で、しつもんはなんでしょうか
impepc

2020/01/03 13:41

言葉足らずですみません。 端的に言えば、○○言語で実装してみた系の記事はよく見かけますが、そのとき仕様が書かれている記事が少ないなと思ったのです。 Clean Architectureはアーキテクチャというくらいなのだから仕様まで考慮して書かれたものだと思います。 実装のみの記事では片手落ちではないか、むしろ、仕様が大事で、なぜこの仕様にしたのかを書くべきではないかという質問です。 言い方を変えると、実装よりも仕様について書くほうがClean Architectureの意図に合うのではないかという疑問です。
y_waiwai

2020/01/03 13:53

で、なにをききたいのでしょうか #未だ意味不明
impepc

2020/01/03 14:08

私の方も質問の具体的な言語化に苦しんでいるのですが、根本には「あの4重丸を前提でコードを書くのはClean Architectureの意図に合っているのか」ですね。 ↓あの4重丸とはこの図です https://images.app.goo.gl/JWWbRxcCMxnd3Aeo6
guest

回答2

0

既に解決済みですが後から見る人のために回答追加しておきます。
クリーンアーキテクチャのレイヤーは向きが重要かつEntityがクリーンに保たれていることが重要なので参照するときにレイヤーを飛ばしても問題ないです。
というか実装すると飛ばさない非常に非効率で無意味になる場面が必ずあらわれます。

DDDについてはこちらで紹介されているのDiscordでみなさん熱心に勉強されているので興味があれば是非参加してみることをおすすめします
https://little-hands.hatenablog.com/entry/dddcj

また私のブログでもクリーンアーキテクチャについて触れているのでよかったら見にきてください。
https://blog.rysh.tech/post/the-origami-architecture/

投稿2020/12/09 07:24

rysh

総合スコア874

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

impepc

2022/03/19 09:36

すみません、1年以上もコメント出来ずに申し訳ありません。 ちゃんとブログを読んでから返信しようと思っていたのですが、 気づいたらあれよとあれよとこんな時期になってしまいました。 せめてブログだけは読んでおこうと思いまして、そうなんだよなーと思うことも多々ありました。 (丸っとインタフェースにしちゃうとモック作るの面倒なんだよなーとか) 簡単なコマンドラインなら飛ばして4重はキツいですし・・・ > クリーンアーキテクチャのレイヤーは向きが重要かつEntityがクリーンに保たれていることが重要なので参照するときにレイヤーを飛ばしても問題ないです。 ありがとうございます。 ちょっと自信がつきました。 勉強会にも参加してみたいのですね(人見知りなのでなんとも・・・)
guest

0

ベストアンサー

例に挙げられた「メール送信システム」がどう言うものを指すのか分かりませんが「メール」は充分 Entitie たり得るように思えます.

「ビジネスロジック上のデータ」なので, 外部のデータとしてどう扱うかとかはあまり関係がないです.

また Clean Architecture における Entities はデータベースなどのエンティティを意味するものではありません.
データを軸とはしますが, ロジックを【含みます】.
名前から勘違いされ易いですが, データ定義【のみを書く層】ではありません.

データを参照するだけのシステムならその参照したデータから紐解いたビジネスロジックは Entitie と言えます.

また多重構造を飛ばしてアクセスすることは御法度です.
層が厚過ぎて何も書かずただ次の層に渡すだけになったとしても, きちんと経由すべきです.

それが億劫なら, Clean Architecture 自体を止めといたほうが良いのでは.
例えば cron + コマンド1行 で済むような内容をふつう Clean にはしませんし.

投稿2020/01/03 23:17

kagilinn

総合スコア354

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

impepc

2020/01/04 04:14

期待した回答が来た気がします。 私が指したメールシステムはsendmailとか、Exchangeのようなメールの送受信だけを指しています。 メールの中身については指していません。なので、その中身が重要ならばEntityに入ると思います(ECサイトの注文書であるとか) ビジネスロジックも確かに原著では「エンティティは、メソッドを持ったオブジェクトかもしれない、あるいは、データ構造と関数の集合かもしれない。エンティティが、大規模プロジェクト内で、たくさんの異なるアプリケーションから使われるのであれば、どちらでも問題ない。」と書かれていますからデータのみと書いてしまってはダメですね。 (訳はココから: https://qiita.com/gki/items/f601afbfada85fd8624e ) ここで、私が気になるのは「層を飛ばしてはいけない」ですね。 私の理解はClean Architectureは依存から発生する問題を解決することが主眼なので、管理し辛いという設計の問題はありますが、依存する層にきちんと従っていれば別に飛ばしてもいいのかなと思いました。 特にEntityですね。例に挙げられたメールでのシステムもEntityに含まれないと思います。 メールの中のデータ(Fromなども含む)はEntityに入るとは思いますがメールの受信などは一番外のUIなどに含まれると思います(そうでないと、webで同じシステムを構築する場合の影響が大きいので) まだ、皆様にはぼんやりしたところがあると思いますが、そんな中、ご回答頂きありがとうございました。
kagilinn

2020/01/13 02:01

色々調べてみたところ, 層を飛ばす例はありました. ただし, 飛ばす際に内外の関係は絶対に崩さないという前提を置いていました. つまり外側から入力したものは必ず (たとえ途中の層を飛ばしても) 最も内部である Entities まで, 途中で折り返したりせず内側へと入力していき, 最も内部である Entities からの出力は必ず (たとえ途中の層を飛ばしても) 途中で折り返したりせず外側へと出力するということのようです.
impepc

2020/01/17 01:11

コメントが遅くなってしまい申し訳ありません。 Entitiesはあるならば4重丸の依存関係の中心なので通らねばならないでしょうね。 確か、Entitiesから処理の順番が出て行く奴はEntitiesでインタフェースを定義して一つ外の層(UseCase)はそれを実装する形じゃなかったかなと。 サンプルコードを用意したいのですが、週末までお待ち下さい。 この記事の感じです。 https://qiita.com/nrslib/items/a5f902c4defc83bd46b8
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問