Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

世界一わかりやすいClean Architecture

15,289 views

Published on

Visual Studio Users Community Japan #1
で発表した資料になります。
https://vsuc.connpass.com/event/143114/

Published in: Engineering
  • Be the first to comment

世界一わかりやすいClean Architecture

  1. 1. 世界一わかりやすいClean Architecture ~ 誤解されがちな二つのことと、おさえるべき二つのこと ~ Atsushi Nakamura
  2. 2. ふたつ質問させてください Copyright 2019 @nuits_jp Slide 2
  3. 3. この図を見たことはありますか? Copyright 2019 @nuits_jp Slide 3
  4. 4. 書籍読んでみましたか? Copyright 2019 @nuits_jp Slide 4
  5. 5. Easiest Clean Architecture Today’s Goal
  6. 6. Today’s Goal 全員が 「クリーンアーキテクチャチョットデキル」 ようになること
  7. 7. Easiest Clean Architecture Overview
  8. 8. Overview Slide 8Copyright 2019 @nuits_jp Clean Architectureの次の点についてお話させていただきます。 • 誤解されがちな二つのこと • おさえるべき二つのこと
  9. 9. Easiest Clean Architecture 注意事項
  10. 10. 注意事項 Slide 10Copyright 2019 @nuits_jp 今日お話しすることは、あくまで私の解釈です • 極端に要約しているので、これがすべてではありません • 書籍の記載とやや矛盾する点もあります しかし、私は今日お話しする二つこそ、Clean Architectureの 本質だと思っています。
  11. 11. 異論・反論大歓迎 Slide 11Copyright 2019 @nuits_jp 異論・反論大歓迎です。※ オンライン・オフラインいずれでも、ぜひご意見を聞かせてください。 ぜひ議論しましょう! ※ 聞く耳持たないマサカリはご遠慮ください
  12. 12. Easiest Clean Architecture About Me
  13. 13. About Me Copyright 2019 @nuits_jp Slide 13 中村 充志 / Atsushi Nakamura • リコージャパン株式会社 所属 • Enterprise(おもに金融)系SIerのITアーキテクト • 「持続可能なソフトウェア」の探求がライフワーク • 2019年の目標 • 「世界一わかりやすいClean Architecture」で登壇したい • 「xUnit & Moqハンズオン」開催 • Blog http://www.nuits.jp • Blog(英語) https://blog.nuits.jp • Twitter @nuits_jp
  14. 14. Easiest Clean Architecture 誤解されがちな二つのこと
  15. 15. Clean Architectureといえば・・・ 出典:TheCleanArchitecture https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html
  16. 16. この図が良くできてい過ぎて誤解を招く Copyright 2019 @nuits_jp Slide 16
  17. 17. ひとつ目の誤解 Clean Architectureとは 「レイヤーをこれらに分割しろ」 という意味でもない 「関心をControllerやUse Case, Entityに分離しろ」 という意味ではないし
  18. 18. ふたつ目の誤解 「PresentationをMVC的に分離しろ(MVVMなどの否定)」 という意味ではないし 「データや処理の流れを一方通行にしろ」 という意味でもない Copyright 2019 @nuits_jp Slide 18 MVC Model(出展Wikipedia)
  19. 19. では、どういう意味か? Copyright 2019 @nuits_jp Slide 19
  20. 20. 図の解釈 「依存性は、内側(上位レベルの方針)だけに 向かっていなければいけない。」※ Slide 20 ※出典:Clean Architecture 達人に学ぶソフトウェアの構造と設計
  21. 21. 図の解釈 こうすればよい ※ 内側の変化に応じて、外側を呼び出したい場合どうすればよいのか? Slide 21 ※ より厳密な意図は後述
  22. 22. Easiest Clean Architecture それあってますか?
  23. 23. はい(当者比)
  24. 24. -The architecture rules are the same! - (邦訳:アーキテクチャのルールはどれも同じである!) 著者は明言しています Copyright 2019 @nuits_jp Slide 24
  25. 25. すべてが同一アーキテクチャに帰結するとすれば 以下は、あくまで一例であることは自明 • レイヤーが4つ※1 • UIがMVC的である • Web限定 • Output PortはUse Caseとの間「だけ」に ある※2 • 中央がDomainじゃなくてEntities ※1 とは限らないと書籍にも明記されている ※2 eventみたいなPub/SubがUseCase限定じゃ困っちゃう
  26. 26. あくまで例示であると取れる記載もある Clean Architecture説明の冒頭に、著名なアーキテクチャ(Hexagonal, Onion, etc...)には類似の共通点が見られるとある。 そして続けてこう記載されている。 The diagram in Figure is an attempt at integrating all these architectures into a single actionable idea. (邦訳:図は、これらのすべてのアーキテクチャを単一の実行可能なアイデアに統合し たものである。) 該当の図は、アーキテクチャは全てClean Architectureで説明可能であることを 例示したモデルであり、Clean Architectureを採用したソフトウェアの具体例の 一つにすぎない Copyright 2019 @nuits_jp Slide 26
  27. 27. どんなソフトウェアにも適用可能な 普遍的なアーキテクチャである だって↓だって言うし -The architecture rules are the same! - (邦訳:アーキテクチャのルールはどれも同じである!) Chean Architectureとは Copyright 2019 @nuits_jp Slide 27
  28. 28. Easiest Clean Architecture おさえるべき二つのこと
  29. 29. ひとつ目 「依存性は、より上位レベルの方針にのみ向けよ」 ふたつ目 「制御の流れと依存方向は分離しコントロールせよ」 おさえるべき二つのこと Copyright 2019 @nuits_jp Slide 29
  30. 30. ひとつ目 「依存性は、より上位レベルの方針にのみ向けよ」 ふたつ目 「制御の流れと依存方向は分離しコントロールせよ」 おさえるべき二つのこと Copyright 2019 @nuits_jp Slide 30
  31. 31. Easiest Clean Architecture さあ具体例を見てみよう!
  32. 32. • SQL ServerのサンプルDB AdventureWorksを利用します • プロダクト別の総売上をCSV出力するコンソール アプリ Overview Copyright 2018 @nuits_jp Slide 32
  33. 33. Software Architecture
  34. 34. ではコードを見てみよう! Copyright 2019 @nuits_jp Slide 34
  35. 35. Not Clean Architecture Copyright 2019 @nuits_jp Slide 35
  36. 36. Not Clean Architecture Copyright 2019 @nuits_jp Slide 36 依存方向 凡例
  37. 37. Software Architecture 依存方向 凡例
  38. 38. Not Clean Architecture Copyright 2019 @nuits_jp Slide 38 依存方向 凡例
  39. 39. という訳で修正してみましょう Copyright 2019 @nuits_jp Slide 39
  40. 40. これでCleanArchitectureになったでしょうか? Copyright 2019 @nuits_jp Slide 40
  41. 41. Copyright 2019 @nuits_jp Slide 41 依存方向 凡例 Clean Architecture ?
  42. 42. Clean Architecture ? Slide 42
  43. 43. Copyright 2019 @nuits_jp Slide 43 依存方向 凡例 Clean Architecture ?
  44. 44. Not Clean Architecture Copyright 2019 @nuits_jp Slide 44 依存方向 凡例
  45. 45. Gatewayはこのままという選択肢はありですが・・・ Copyright 2019 @nuits_jp Slide 45
  46. 46. Software Architecture 依存方向 凡例
  47. 47. DBを呼び出さないといけないのに無理じゃない? Copyright 2019 @nuits_jp Slide 47
  48. 48. • SQLを利用しないという意味ではない • RDBというアーキテクチャには依存する • 永続化データのスキーマに依存しないという意味 DBからGatewayへ依存させるとは? Copyright 2019 @nuits_jp Slide 48
  49. 49. Not Clean Architecture Copyright 2019 @nuits_jp Slide 49 依存方向 凡例
  50. 50. Gatewaysのクラス図とER図 Copyright 2018 @nuits_jp Slide 50 dm SalesOrderDetail and Product Product «column» *PK ProductID: int * Name: nvarchar(50) * ProductNumber: nvarchar(25) * MakeFlag: bit = 1 * FinishedGoodsFlag: bit = 1 Color: nvarchar(15) * SafetyStockLevel: smallint * ReorderPoint: smallint * StandardCost: money * ListPrice: money Size: nvarchar(5) FK SizeUnitMeasureCode: nchar(3) FK WeightUnitMeasureCode: nchar(3) Weight: decimal(8,2) * DaysToManufacture: int ProductLine: nchar(2) Class: nchar(2) Style: nchar(2) FK ProductSubcategoryID: int FK ProductModelID: int * SellStartDate: datetime SellEndDate: datetime DiscontinuedDate: datetime * rowguid: uniqueidentifier = newid() * ModifiedDate: datetime = getdate() SalesOrderDetail «column» *pfK SalesOrderID: int *PK SalesOrderDetailID: int CarrierTrackingNumber: nvarchar(25) * OrderQty: smallint *FK ProductID: int *FK SpecialOfferID: int * UnitPrice: money * UnitPriceDiscount: money = 0.0 * LineTotal: numeric(38,6) * rowguid: uniqueidentifier = newid() * ModifiedDate: datetime = getdate() クラス図 ER図 Gatewaysが完全にデータベースの文脈で記述されている
  51. 51. Gatewaysのクラス図とER図 Copyright 2018 @nuits_jp Slide 51 dm SalesOrderDetail and Product Product «column» *PK ProductID: int * Name: nvarchar(50) * ProductNumber: nvarchar(25) * MakeFlag: bit = 1 * FinishedGoodsFlag: bit = 1 Color: nvarchar(15) * SafetyStockLevel: smallint * ReorderPoint: smallint * StandardCost: money * ListPrice: money Size: nvarchar(5) FK SizeUnitMeasureCode: nchar(3) FK WeightUnitMeasureCode: nchar(3) Weight: decimal(8,2) * DaysToManufacture: int ProductLine: nchar(2) Class: nchar(2) Style: nchar(2) FK ProductSubcategoryID: int FK ProductModelID: int * SellStartDate: datetime SellEndDate: datetime DiscontinuedDate: datetime * rowguid: uniqueidentifier = newid() * ModifiedDate: datetime = getdate() SalesOrderDetail «column» *pfK SalesOrderID: int *PK SalesOrderDetailID: int CarrierTrackingNumber: nvarchar(25) * OrderQty: smallint *FK ProductID: int *FK SpecialOfferID: int * UnitPrice: money * UnitPriceDiscount: money = 0.0 * LineTotal: numeric(38,6) * rowguid: uniqueidentifier = newid() * ModifiedDate: datetime = getdate() クラス図 ER図 Gatewaysが完全にデータベースの文脈で記述されている 実際にはこの4項目しか 必要ない
  52. 52. たとえば・・・ • 他機能の変更で列が増える • 影響がほぼないことは分かりきっている • しかし回帰テストはせざるを得ない テーブルの構造にダイレクトに依存してしまうと・・・ Copyright 2019 @nuits_jp Slide 52
  53. 53. Software Architecture 依存方向 凡例
  54. 54. ひとつ目 「依存性は、より上位レベルの方針にのみ向けよ」 ふたつ目 「制御の流れと依存方向は分離しコントロールせよ」 おさえるべき二つのこと Copyright 2019 @nuits_jp Slide 54
  55. 55. 本質的に大切なのは文脈である Copyright 2019 @nuits_jp Slide 55
  56. 56. Not Clean Architecture Copyright 2019 @nuits_jp Slide 56 依存方向 凡例 ここで言うGatewaysのDB依存とは ✖ DBを呼び出しているから 〇 DBの文脈(スキーマ)で記述されているから
  57. 57. Not Clean Architecture Copyright 2019 @nuits_jp Slide 57 依存方向 凡例 DBがGatewaysの文脈で定 義されていればよい ???
  58. 58. CQRSを使え Copyright 2019 @nuits_jp Slide 58
  59. 59. CQRS :Command-Query Responsibility Segregation データベースの操作を次のふたつの責務に完全に分離する方法論 1. データベースを更新するCommand 2. データベースを参照するQuery 今回のケースはQueryに該当するため Gatewayの文脈でQuery用のDBオブジェクトを用意します。 CQRSとは Copyright 2019 @nuits_jp Slide 59
  60. 60. 完ぺきなCQRSを適用するのは難しい。 また、場合によってはオーバースペックでさえある。 1. CommandとQueryのデータソースの完全分離 2. ドメインイベント 3. 非同期メッセージ 4. イベントソーシング 5. 結果整合性 6. などなど そこで今日は、データベースのViewを使った軽量な方法論を紹介します※ ※ 必ずしもViewを使えという訳ではない とはいえ・・・ Copyright 2019 @nuits_jp Slide 60
  61. 61. これがCleanなArchitectureだ! Copyright 2019 @nuits_jp Slide 61 ※ 言い過ぎです
  62. 62. Clean Architecture Copyright 2019 @nuits_jp Slide 62 依存方向 凡例
  63. 63. Clean Architecture! Slide 63※ 言い過ぎでもないです このアーキテクチャの完璧な再現性を見てください!
  64. 64. CQRSと類似概念にCQSがある • コマンドクエリ分離原則(Command-Query Separation) 雑に言うと・・・ • CQRSはデータソースに対するパターン • CQSはクラスに対するパターン DBの文脈をGatewayで吸収する選択をする場合はCQSも検討する CQSについて Copyright 2019 @nuits_jp Slide 64
  65. 65. Easiest Clean Architecture 制御の流れと依存関係の分離
  66. 66. 制御の流れと依存関係の分離 凡例 制御の流れ 依存方向 アプリケーション コード データベース オブジェクト 一般的に 制御の流れ=依存方向 になりがち <<具象概念>> <<具象概念>> Slide 66
  67. 67. 制御の流れと依存方向は分離しコントロールできる Copyright 2019 @nuits_jp Slide 67
  68. 68. 制御の流れと依存関係の分離 凡例 制御の流れ 依存方向 アプリケーション コード データベース オブジェクト そのためには関係のコントラクト(契約・仕様・お約束) のコンテキスト(文脈)を制御する <<具象概念>> <<具象概念>> コントラクト <<抽象概念>> それぞれの具象概念は抽象的な契約(仕様)に依存する Slide 68
  69. 69. 契約の文脈をコントロールする アプリケーション コード <<具象概念>> コントラクト <<抽象概念>> データベース オブジェクト <<具象概念>> Slide 69 アプリケーション コード <<具象概念>> コントラクト <<抽象概念>> データベース オブジェクト <<具象概念>> 凡例 制御の流れ 依存方向 文脈
  70. 70. -The architecture rules are the same! - Copyright 2019 @nuits_jp Slide 70
  71. 71. システム サブシステム コンポーネント ソフトウェアのフラクタル Copyright 2018 @nuits_jp Slide 71 クラス サブシステム クラス コンポーネント クラス クラス ソフトウェア エンティティすべてに、ここまでの話は適用可能 • 要素間のインターフェースの文脈により、制御の流れと依存関係は制御可能 • 依存関係によって、安定性と柔軟性をコントロール可能 ソ フ ト ウ ェ ア エ ン テ ィ テ ィ
  72. 72. ソフトウェア エンティティ 代表的なコントラクト システム OpenAPI(なんならCSVのFTP転送) サブシステム OpenAPIやSwagger コンポーネント プログラム インターフェース クラス プログラム インターフェース ソフトウェア エンティティとコントラクト Copyright 2018 @nuits_jp Slide 72
  73. 73. 文脈によって、制御の流れと依存方向は分離し制御せよ クライアント エンティティ <<具象概念>> コントラクト <<抽象概念>> サーバー エンティティ <<具象概念>> Slide 73 クライアント エンティティ <<具象概念>> コントラクト <<抽象概念>> サーバー エンティティ <<具象概念>>
  74. 74. -The architecture rules are the same! - Copyright 2019 @nuits_jp Slide 74
  75. 75. Easiest Clean Architecture まとめ
  76. 76. まとめ Slide 76Copyright 2019 @nuits_jp • Clean Architectureとは、どんなソフトウェアにも適用可能な普遍的な アーキテクチャである • Clean Architectureは、次のふたつを誤解されがち • 参考図の通りに関心を分離するのがClean Architectureである • PresentationとModelの境界はInputとOutputを分離すべし • 次のふたつを理解せずClean Architectureは語れない • 依存性は、より上位レベルの方針にのみ向けよ • 制御の流れと依存方向は分離し制御せよ
  77. 77. ThankYou! Any Questions?

×