<style> .rainbowText{ background: linear-gradient(to right,#e60000,#f39800,#fff100,#009944,#0068b7,#1d2088,#920783); -webkit-background-clip: text; -webkit-text-fill-color: transparent; font-size: 100%; font-weight: bold; display: inline-block; } </style> # CleanArchtecture読書会 # 第一部 イントロ ### *2つの価値*のお話 * 「振る舞い」と「構造」 * 振る舞い:ステークホルダーのマシンが要件を満たせるようにすること * 構造:変更がしやすいこと * 形状にとらわれないアーキテクチャにしたほうが実用的 * 新しい機能が形状に適さないこともあるので * 現在の機能を重視しすぎて変更可能性が疎かになるという間違いが多い * 「機能の緊急性よりもアーキテクチャの重要性」をちゃんと認識すべし --- # 第二部 構成要素から始めよ:プログラミングパラダイム *コンパイラという言葉を作ったのはGraceHopper #ch3 パラダイムの概要 3つのプログラミングパラダイム(何をすべきではないかをプログラマに伝えている) * 構造化プログラミング * [Edsger_W._Dijkstra](https://en.wikipedia.org/wiki/Edsger_W._Dijkstra) * GOTO文やめた * 直接的な制御の移行に規律を課す * OOP * C#,Javaとか * [ALGOL言語](https://ja.wikipedia.org/wiki/ALGOL) * 間接的な制御の移行に規律を課す * 関数ポインタ辞めた  >[name=yuriemori]間接的な制御の移行に規律を課す? >グローバル変数とか別のところにある関数を使えないようにする→カプセル化・隠蔽 >カプセル化して他領域から簡単に制御できないように >mutableの導入? > * 関数型プログラミング * シンボルの値は変化しない * 代入文がないor厳しい * 代入に規律を課す  >Rustとか >代入文がないとは? >→mutableにしないと可変にならない。https://tourofrust.com/04_ja.html >オブジェクト指向っぽくも書けはする >C++からモダンにするために移行したりとか アーキテクチャの関心ごと * コンポーネントの分離 * データ管理 * 機能 ## Ch.4構造化プログラミング https://ja.wikipedia.org/wiki/%E6%A7%8B%E9%80%A0%E5%8C%96%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0 ダイクストラのすごいところ→プログラムの構造を数学の証明に基づいて追った * 列挙→Enum (もしくはlist) * [GOTO](https://ja.wikipedia.org/wiki/Goto%E6%96%87)は悪(Dijkstraの主張) >[name=yuriemori]goto文の消滅が構造化プログラミング(→モジュール化)の始まりととらえてよい? >CACMhttps://cacm.acm.org/ * GOTOがないとモジュールの機能分割が可能になる * プログラムの正しさをどうやって証明するか? → 証明はできないが反証はできる * プログラムが正しいことは証明できないが、プログラムが間違っていることは証明できる(→プログラムは反証可能である) * 結局プログラムを数学的に証明しよとしたDijikstraの夢は叶わなかった、、、 * テストとは、「ソフトウェアにバグが存在する」ことを示す。 * 構造化プログラミングは全ての基本 * 「機能分割」は、プログラムを反証可能な単位に分割する意味がある * [ダイクストラ法](https://www.wikiwand.com/ja/%E3%83%80%E3%82%A4%E3%82%AF%E3%82%B9%E3%83%88%E3%83%A9%E6%B3%95)の人 ### オブジェクト指向プログラミング * 優れたアーキテクチャはオブジェクト指向の原則を理解・運用していること * オブジェクト指向→カプセル化・継承・ポリモーフィズム。。。って思ってるだろうけど、別にそれはOO言語より前の言語(C)でもできる * けど、OOによってそれらを安全に、便利に使うことができるようになった※IO→https://ja.wikipedia.org/wiki/Io_(%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E8%A8%80%E8%AA%9E) * ポリモーフィズムによってソフトウェアの依存関係から自由になれる(依存関係の逆転)。→それこそがOOの強力なパワーだ! * でもポリモーフィズムは継承ありきだし Dahlと[Nygaard](https://www.wikiwand.com/ja/%E3%82%AF%E3%83%AA%E3%82%B9%E3%83%86%E3%83%B3%E3%83%BB%E3%83%8B%E3%82%B4%E3%83%BC%E3%83%AB)が1996年にオブジェクト指向を発表 結局オブジェクト指向はなにがやりたいのか? * [カプセル化](https://ja.wikipedia.org/wiki/%E3%82%AB%E3%83%97%E3%82%BB%E3%83%AB%E5%8C%96) * データと関数の周囲に線を引くことによって外側からデータが見えないようにする →privateというやつ * OO言語じゃなくてもカプセル化はできる * 実際のOO言語で完璧なカプセル化を実装しているわけではない * 「カプセル化されたデータに勝手にアクセスしてはいけない」という思想には依存している * JSはOOなのか、、、(functionalっぽい感じもする)? * 継承 * データ構造のなりすまし?が簡単になった * 以前から派生した構造を代入することができたが、OO言語ではアップキャスティングを自動でやってくれるようになった ここまでは別にOO以前の言語(C)でもできてたからそこまで画期的でもない そもそもC#とかがCを基にしてるからOOじゃないCでもできるっていうのは当然と言えば当然 * [ポリモーフィズム](https://ja.wikipedia.org/wiki/%E3%83%9D%E3%83%AA%E3%83%A2%E3%83%BC%E3%83%95%E3%82%A3%E3%82%BA%E3%83%A0) * 関数ポインタの応用でOO以前の言語でもできはする * 関数ポインタは危険 * プログラマがポインタを解した関数の呼び出し順序を覚えておかなくては行けない * ポインタがめっちゃわかってるつよつよエンジニアじゃないとちゃんと実装できなくてしんどい * バグの温床になりやすい,可読性下がる ref: [関数へのポインタ wiki](https://ja.wikipedia.org/wiki/%E9%96%A2%E6%95%B0%E3%81%B8%E3%81%AE%E3%83%9D%E3%82%A4%E3%83%B3%E3%82%BF), [ポインタ wiki](https://ja.wikipedia.org/wiki/%E3%83%9D%E3%82%A4%E3%83%B3%E3%82%BF_(%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0)) ## 関数型プログラミング Lisp言語:AI研究者JohnMcCarthyが開発。AI研究で普及。 Lispが現代のプログラミング言語に与えた影響は大きいものです。自分自身を評価するeval関数を発明したことを始め、木構造、ガベージコレクション、動的型付け、条件分岐、高階関数、再帰など、現代のプログラミング言語に欠かせない要素を先取りして実装していました。 https://news.mynavi.jp/article/programinglanguageoftheworld-18/ 関数型言語(例) * Scala * Haskell ※Js,Pythonは割と手続き型言語 プログラミング言語のパラダイムシフトにより奪われたもの →goto、関数ポインタ、代入(1958~1968年の10年で奪われた) * パラダイムの歴史的な教訓はアーキテクチャのすべてに関係している * 「アーキテクチャの境界を超えるためにポリモーフィズムを使う」 →継承すると継承元のインターフェイスとかクラスのメソッドが使えること? アーキテクチャの大きな関心事 とは「コンポーネントの分離」「データ管理」「機能」 オブジェクト指向プログラミングによるカプセル化やポリモーフィズムはコンポーネントの分離に繋がり、 関数型プログラミングのパラダイムシフトはデータの配置やアクセスへの規制によってアーキテクチャのデータ管理に影響を与えた * 関数型プログラミングでは変数の書き換えはしない →メモリをあまり使わないで済む ([参照](https://stackoverflow.com/questions/4522304/does-functional-programming-take-up-more-memory)) ## 構造化プログラミング * 順次・選択・反復を数学的に証明 * [ユークリッド幾何学](https://ja.wikipedia.org/wiki/%E3%83%A6%E3%83%BC%E3%82%AF%E3%83%AA%E3%83%83%E3%83%89%E5%B9%BE%E4%BD%95%E5%AD%A6) * ダイクストラの主張 * gotoはクソ * 機能分割ができない、反証可能ではないから * プログラムが正しいということを証明することはできないが、十分に正しいということを証明することはできる(→プログラムは反証可能) * coverageという概念に繋がる? * テストはバグが存在しないことではなく、バグが存在することを証明することができる(byダイクストラ) まとめ:ソフトウェアの本質は、順次・選択・反復・間接参照で構成されている --- # 第3部 設計の原則 ### SOLID原則: #### 1.単一責任の原則(SRP) モジュールはたったひとりのアクターに対して責任を負うべきである ※アクター:変更を望む人たち 以下の設計にするのがよい Facadeクラス→メソッドをまとめておくクラス 具体的なImplementaionをするクラス データ構造を入れるクラス #### 2.オープン・クローズドの原則(OCP) ソフトウェアの構成要素は拡張に対しては開いていて、修正に対して閉じていなければならない。 OCPの原則に基づいた最強のアーキテクチャ DataBase Interactor Controller Presenter Views Controllerへの変更がInteractorに影響を及ぼさないようにすることが最優先ではあるが、ControllerもまたInteractorの変更から保護しておきたい。そのために、Interactorの内部を隠蔽しているのである。 #### 3.リスコフの置換原則(SOLIDのL):LSP 置換できるやつが派生型 SuperClass→SubClass arraylistを宣言するときにlistを定義する的な? LSPに違反するとif文をたくさん書かなきゃいけなくなる→アーキテクチャが特別な仕組みだらけになる #### 4.インターフェイス分離の原則(SOLIDのI) 各操作をインターフェイスに分離せよ(依存させないように) #### 5.依存関係逆転の原則(DIP) ソースコードの依存性と処理の流れは逆向き ~~動的型付け言語→コンパイラがいらない 静的型付け言語→コンパイラがいる~~ 「静的型付け言語/動的型付け言語」と「コンパイル型言語/インタプリタ型言語」は直交する概念である 実装クラスを他で使わないときも依存関係逆転の原則を守るべきか? 依存関係が成立しないなら守らなくてもよさそうだけど、今後の拡張性を考えたらこの原則を守ったがよさそう **JavaだとSpringってフレームを使えばいい感じにSOLIDを守った実装ができる** C#だとASP.NetのMVC --- # 第4部 コンポーネントの原則 コンポーネント:デプロイの単位 [PDP-8](https://ja.wikipedia.org/wiki/PDP-8): プログラマがメモリ上のどこにロードするか決めないといけなかった時代(1960年代) Relocatability(再配置可能性) Linker 気軽に使えるコンポーネントプラグインアーキテクチャを手に入れるまで60年代から50年代ぐらいかかった # 第13章 コンポーネントの凝集性 C#でのライブラリの依存性の管理→[Nuget](https://docs.microsoft.com/en-us/nuget/what-is-nuget) JavaではMaven Ruby→Rubygems * 再利用・リリース等価の原則 コンポーネントの単位=リリースの単位にすること * 閉鎖性共通の原則 単一責任の原則をコンポーネントまで拡張 コンポーネントを変更する理由が複数あるべきではない open-closedの原則とも関連 * 全再利用の原則 密接に係わるクラスはまとめること。関係のないものはまとめないこと。 SOLIDのインターフェイス分離の原則をクラスのレベルまで拡張した原則 SOLID KISS DRY YAGNI YouAren'tGoingtoNeedIt SLAPSingleLevelofAbstractionPrinciple 抽象レベルの統一 OCP ## 第14章 コンポーネントの結合 政治的=businesslogic? レガシーコード? A→BはOK B→A,C→Aとかが駄目 二日酔い症候群:同じソースファイルを弄ってるとき、誰かの変更のせいでコードが動かなくなっちゃった(´;ω;`) を回避するためには? →Git使えばよくね? →TFSでもマージする前conflict起きてるよ!ってwarningされるし、そもそもチェックイン時に自動テスト回してダメだったらロールバックすればよくね? SOLIDが提唱されたのが2000年のRobertC.MartinのDesignPrinciplesandDesignPatterns * 週次ビルド * ADP(非循環依存関係の原則) [cleanCode](https://www.amazon.co.jp/Clean-Code-%E3%82%A2%E3%82%B8%E3%83%A3%E3%82%A4%E3%83%AB%E3%82%BD%E3%83%95%E3%83%88%E3%82%A6%E3%82%A7%E3%82%A2%E9%81%94%E4%BA%BA%E3%81%AE%E6%8A%80-%E3%82%A2%E3%82%B9%E3%82%AD%E3%83%BC%E3%83%89%E3%83%AF%E3%83%B3%E3%82%B4-%EF%BC%B2%EF%BD%8F%EF%BD%82%EF%BD%85%EF%BD%92%EF%BD%94-%EF%BC%A3%EF%BC%8E%EF%BC%AD%EF%BD%81%EF%BD%92%EF%BD%94%EF%BD%89%EF%BD%8E-ebook/dp/B078HYWY5X/ref=sr_1_1?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&crid=DYQ5M5M8J7DT&dchild=1&keywords=clean+code+%E3%82%A2%E3%82%B8%E3%83%A3%E3%82%A4%E3%83%AB%E3%82%BD%E3%83%95%E3%83%88%E3%82%A6%E3%82%A7%E3%82%A2%E9%81%94%E4%BA%BA%E3%81%AE%E6%8A%80&qid=1628167990&sprefix=clean+code%2Caps%2C312&sr=8-1)のやつ [clean codeの帽子](https://www.google.com/search?q=red+green+refactoring+cap&tbm=isch&source=iu&ictx=1&fir=BLJVoAaCuLbuJM%252CrXwkPChFKMyIyM%252C_&vet=1&usg=AI4_-kRxXHPruPDGtT_yrQwMFE-3P5OKNg&sa=X&ved=2ahUKEwjy6OuE9pnyAhVStKQKHZKXCxoQ9QF6BAgVEAE) ### 循環依存の何が辛いのか * 影響範囲が広くなってconflictのリスクが高まる(リリースするのが難しくなる) * 二日酔い症候群(conflict)に悩まされる * 影響範囲が広くなってテストがめんどくさい TDDでやってればこんなことは起きないのに、、、 front-endのテストの場合、コンポーネントがレンダリングされるかとか Jsのテストの場合は[Jest](https://jestjs.io/docs/expect)とか コンポーネント=デプロイの最小単位 抽象(Instability)度の高さ=安定性のたかさ  I=0→安定している I=ファン・アウト/(ファン・イン+ファン・アウト) ファン・アウト=コンポーネント内のクラスに依存している外部のコンポーネントの数 ファン・イン=外部のコンポーネントに依存しているクラスの数 A=抽象度 苦痛ゾーン(抽象度が低く安定性が低い) インターフェイスとかなんもなくて、DBにつなぐ処理とか依存性の高い処理なのに100行のメソッドとかクソみたいなやつ(変動制が高くて依存性が高いのがここにあると最悪) stringとか変動制の低いやつは別にここにあっても問題ない 無駄ゾーン 抽象的なのに使われてない→ゴミ 距離(Distance)D=|A+I-1|値が0=そのコンポーネントは主系列に近い 標準偏差(Z=1)標準偏差=データの散らばり具合を図る 第5部 アーキテクチャ ソフトウェアアーキテクトもコードを書くべし!!!->コードを書かないアーキテクトはダメだ アーキテクチャの戦略:出来るだけ長い期間、出来るだけ多く選択肢を残すこと monolithic=>microserviceの逆 分割されていないシステム デプロイのコスト=システムの有用性 開発・デプロイ・運用・保守 Operatorの仕事=デプロイ、テーブル設計のレビュー、サーバー作業 アーキテクチャを慎重に考えれば保守のコストは大幅に下がる 振る舞いの価値<構造の価値 やりたいことだけ聞いて技術の選択肢の幅を大きくする プラグイン:プラグイン(Plugin)は、本来「差込口」の意味だが、IT用語としては、アプリケーションの機能を拡張するソフトウェアを指す。 ## 第22章 クリーンアーキテクチャ Entities(ビジネスロジックの中核的な所)から実装するべき テーブル設計とかは後でやる HelixArchitectureはクリーンアーキテクチャっぽい? ![clean architecture structure](https://i.imgur.com/Q64d1Q3.png) ## 第23章 プレゼンターとHumbleObject プレゼンター: HumbleObjectパターンの一種であり、アーキテクチャの境界の特定と保護に役立つもの HumbleObjectパータン: UnitTestを書くときに、テストしやすい所とテストしにくい所を分離させるためにできたデザインパターン。 テストしにくい所が含まれているモジュールがHumbleObject(必要最低限のことしかさせないからHumble)であり、 テストしやすい所がPresenter Hibernate:DBの呼び出しを簡単にしてくれるJavaのFramework オブジェクトとDBのデータをマッピングしてくれる UI=View=html,css(テストしなくてもいいところ) ViewModel=JS,Angularとか [Humble Objectパターン](https://shtnkgm.com/blog/2020-05-17-humble-object-pattern.html) ## 第26章 メインコンポーネント Main:ほかのコンポーネントを作成・調整・監督 ## 第27章 サービス:あらゆる存在 最近流行りのサービス指向アーキテクチャ(SOA)とマイクロサービスアーキテクチャのサービスとは何ぞやということを考えている SOAがなんで流行ってるのか? ・サービスが互いに分離されているように見えるから。 ・サービスが開発とデプロイを分離させている。 →どっちも部分的である。 アーキテクチャにとって重要なサービスとは? DevOps:https://azure.microsoft.com/ja-jp/overview/devops-vs-agile/ DeveloperとOperatorがいい感じにコラボレートしていい感じにソフトウェアデリバリーをやろうという思想。 OCP オープン・クローズドの原則: 拡張に対しては開いていて、修正の為には閉じていなければならない ## 28章:テスト境界について SOLID | 項目 | 意味 | 英語 | | ---- | -------------------------- |:------------------------------------- | | S | 単一責任の原則 | (SRP:Single Responsibility Principle) | | O | オープン・クローズドの原則 | (OCP:Open-Closed Principle) | | L | リスコフの置換原則 | (LSP:Liskov Substitution Principle) | | I | インターフェイス分離の原則 | (ISP:Interface Segregation Principle) | | D | 依存関係逆転の原則 | (DIP:Dependency Inversion Principle) | ・テストはシステムの一部。 ~~### システムコンポーネントとしてのテスト ・テストはアーキテクチャの円の最も外側にあると考えられる。 ・テストは最も独立したシステムコンポーネント~~ 面倒なテストを作るとシステムも面倒になる。 いじるのが大変でレガシー化することも。→テストはうまく設計すべきシステムの一部。 ## 第29章 クリーン組込みアーキテクチャ ソフトウェア vs ファームウェア (寿命長い)   (ハードウェアが進化→時代遅れに) [?]ファームウェア、ミドルウェア、OSの違いは? [ミドルウェア](https://www.kumikomi.jp/middleware):OSとソフトウェアの中間 例)SQLデータベース、Webサーバーなど ファームウェア:機器の内部に固定的に組み込まれる。 例)D-Sub(Bluetoothの前身) ### 適正テスト Kent Beckによるソフトウェアを構築する3つの活動 1. まずは動作させる。**動作しなければ仕事にならない** 2. それから、正しくする。**あなたやほかの人たちが理解できるようにコードをリファクタリングして、ニーズの変化や理解の向上のためにコードを進化させていく。** 3. それから、高速化する。**「必要とされる」パフォーマンスのためにコードをリファクタリングする。** cf.Kent Beckによる書籍 TDD、リファクタリングなど? [?]組み込みソフトウェアとファームウェアの違いは? 組み込みソフトウェアの中の硬い部分、硬いソフトウェア、 ~~なんかわからんけど動いているからよし!~~ ↑よくない アプリを動作させること(=**適正テスト**) だけでなく、長寿になるコード(クリーン組込みアーキテクチャ)を考える必要がある。 ### ターゲットハードウェアのボトルネック ### クリーン組み込みアーキテクチャはテスト可能な組込みアーキテクチャ #### レイヤー ソフトウェア/ファームウェア/ハードウェア #### ハードウェアは詳細 ムーアの法則: 同じメモリ数のハードは2年後には半額になる ソフトウェアとファームウェアを混ぜると変更しにくい・変更すると意図しない結果につながりやすい。 ハードウェア抽象化レイヤー (HAL:Hardware Abstraction Layer) ソフトウェアとファームウェアの境界 ### ハードウェアの詳細はHALのユーザーに明らかにしない #### プロセッサは詳細 **2022/03/10 The Mint Day🌿🌿🌿** クリーン組込みアーキテクチャのソフトウェアのいいこと * ターゲットハードウェアをオフにしたテストが可能 * HALを活用 → オフターゲットのテストを簡単にする継ぎ目や置換点ができる。 **<i>便利</i>**(組込みアプリケーションのプロセッサの機能に対応する、特殊なツールチェーン) な 機能を使っているコードは「もはやC言語ではない」。 **2022/03/17 St. Patrick's Day ☘☘☘** 「では、ACME社製のDSPのヘッダーファイルを見てみよう( ワイリー・コヨーテが使っていたアレだ)。」から (ワイリー・コヨーテはアメコミのキャラクター。トムジェリのジェリーっぽい生き物。) 低レベル機能(大文字変数、ファームウェアに直にアクセスする)もの ・ファームウェ ・プロセッサ抽象化レイヤー(PAL:Processor Abstraction Layer)でファームウェアから分離する。 特定の言語の拡張を使わないといけない書き方を避ける [デバイスレジスタはシステム(OS)とデバイスを通信させるために存在するレジスタです。IOポートとも呼ばれます。](https://sciencepark.co.jp/device_driver/dvdr/report-6/) [マイクロコントローラ (microcontroller) とは、主に電子機器などの組み込みシステムに使われる集積回路のひとつ。電子機器の制御用に最適化されたコンピュータの一種である。略してマイコンとも呼ばれる。](https://ja.wikipedia.org/wiki/マイクロコントローラ) ### OSは詳細 プリミティブ:原始的な 新しいOSの変更前の中核みたいな意味 https://www.amazon.co.jp/dp/B071V7MY82/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1 **2022/03/24 ** ## 第30章 データベースは詳細 データベース ≠ エンティティ ### リレーショナルデータベース RDB:1970年~ SQLはいつから?→[1974年から] https://en.wikipedia.org/wiki/SQL#History SQL serverから受け取ったデータをオブジェクトに格納する C#だとSqlDataReaderClass https://docs.microsoft.com/ja-jp/dotnet/api/system.data.sqlclient.sqldatareader?view=dotnet-plat-ext-6.0 RDBを使う際はRDMSとセットになる RDB:Oracle, SQL sever RDMS:SQL Server Management Studio(SSMS)とか データこそが重要であり、データベースは詳細である ## 第31章 ウェブは詳細 計算能力はどこにあるべき? 集中or分散? 集中するとしたらどこ? web1.0ではサーバーに、Web2.0ではだんだんクライアント側に | version | 時代 | 説明 | | -------- | -------- | -------- | | Web1.0 | 1970s~ | サーバー側に計算パワーを全集中=Backendでたくさん処理 | | Web2.0 | 1990s~ | JavaScript, Ajaxの登場で、フロント側でもBackendで書いてたような処理が書けるようになった=ユーザーがコンテンツを生成(ブログとか個人HPみたいにユーザーもコンテンツ作成に参入できるように) | | Web3.0 | 2020s~? |ユーザーがコンテンツを所有(ブロックチェーン、NFT、ローコードのぽかげでこれまでになく簡単にコンテンツの所有、管理、売買が可能に)、セキュリティ技術の向上 | [web3 とは](https://www.gartner.co.jp/ja/articles/what-is-web3) ビジネスルール≠UI 1. ビジネス側が要件を提示 ↓ 2. UI/UXデザイナーがデザイン ↓ 3. 実装(FeD, BeD) ビジネスルール=UIになるとしたら1と2を同じ人がやってる? UXという概念はいつから? →1990年代辺り(Web2.0の時代と重なる) *2022/04/28 🍀四葉の日🍀 👨‍💻労働安全衛生世界デー👩‍💻 🍷The German Wine Day🍷* ## 第32章 フレームワークは詳細 ### フレームワークの作者たち * フレームワークは自分のために作られたわけではない * フレームワークはアーキテクチャではない。 フレームワークの例:React, Angular, blazor(C#), Spring(Java),Django(Python), ASP.NET, [C# で出来ること一覧](https://qiita.com/okazuki/items/e3a8e23f9ac2a10d8fde) ### 一方的な結婚 作者:アプリケーションとフレームワークを結合したい。    利用者にもアプリケーションとフレームワークを結合してほしい! ### リスク * アーキテクチャに問題(円のもっとも内側に入り込む→依存性のルールに違反する) * プロダクトが成長すると、フレームワークの提供する機能では手が負えなくなるかも * フレームワークの進化とプロダクトの方向性の違い * もっと優れたフレームワークに乗り換えたくなる  (?)フレームワークの変更したことはある? ### 解決策 フレームワークを使うことは問題ないが、結合せず一定の距離を保つこと!! フレームワーク関連をコンポーネントにまとめてプラグインする? ex)Springを使って(アーキテクチャの中で最下位レベルの)Mainコンポーネントに依存性を注入する。 ### 今あなたたちを夫婦として宣言する どうしても"結婚"せざるを得ない→縛られる*決断*を覚悟して使うこと! ### まとめ フレームワークはむやみに使わない、使うときはアーキテクチャの境界から可能な限り遠ざける。 *2022/05/12* 👩‍⚕️看護の日👨‍⚕️ ## 第33章 事例:動画販売サイト ### プロダクト アクターとユースケースを決める ### ユースケース分析 (図33-1) ★DDDに似ているが、DDDはサービス側から決めている(アクターから決めない) ★ユースケース分析はアクターから決める 抽象ユースケース:(点線)全般的な方針 例)「カタログを閲覧する」 「購入者としてカタログを閲覧する」「閲覧者としてカタログを閲覧する」 →継承 ★開発者もテストコードを短くできてうれしい! *2022/05/19* ### コンポーネントアーキテクチャ ![](https://i.imgur.com/GoExTbg.png) デプロイするコンポーネントを必要に応じて切り離す。 ### 依存性管理 * オープン・クローズド の 原則( OCP):継承の関係は制御の流れと逆向き 依存性の向きを正しい方向に → 下位レベルの詳細が変わっても上位レベルの方針には影響しないようにする。 ### まとめ アーキテクチャ図の 単一責任の原則(SRP)によるアクターによる分割 依存性のルールによる分割 (試験や面接によく出る)スクラムデベロッパーの試験 依存性の注入:アノテーション javaでは「[オートワイヤー](https://spring.pleiades.io/spring-framework/docs/current/javadoc-api/org/springframework/beans/factory/annotation/Autowired.html)」がある C#では「[リフレクション](https://docs.microsoft.com/ja-jp/dotnet/csharp/programming-guide/concepts/reflection)」 Pythonでは「[デコレーター](https://www.python.ambitious-engineer.com/archives/286)」(アノテーションもあるが別物でただの注釈) 上位は下位を考慮せずにクラスだけ気にすればいい <p class="rainbowText">MDでもHTML使用可能です。虹色グラデーションテキスト。</p> https://csshtml.work/rainbow/ ## 書き残したこと by [**Simon Brown**](https://simonbrown.je/) レイヤーで設計を分ける: control, service, repositoryなどのレイヤーでパッケージを分ける →ソフトウェアが大きくなった時に大変 機能で設計を分ける:水平方向に、例えばOrdersなどでパッケージを分ける →これにも問題がある ### BCE(boundary-control-entity) - Entity-control-boundary Entityが内側で、外部とやりとりがある部分が外側 内側は絶対に外部にふれない ***2016/06/16*** (復習) ### ポートとアダプター (第22章)アンクル・ボブ → 「 ポート と アダプター」「 ヘキサゴナルアーキテクチャ」「 BCE」 などの 手法 → ビジネスに関するコード(ドメイン)と技術的な実装(フレームワークやDB)から切り離す 内側(ドメイン)と外側(インフラストラクチャ)に分けたコードベースが多い。 <p class="rainbowText">★大原則:内側が外側に依存しない!!</p> JDBC=Java Database Connectivity ・JDBCレポジトリ…DBのレポジトリ #### 機能によるパッケージング vs 外側に依存しないパッケージング ![機能によるパッケージング vs 外側に依存しないパッケージング](https://i.imgur.com/KKnLM05.png) <p class="rainbowText">図34-4で OrdersRepository → Orders  ドメイン駆動設計より、「内部」に属するものはユビキタス言語での名づけ推奨</p> [ユビキタス言語](https://zenn.dev/leaner_tech/articles/20210922-ubiquitous-language) = 開発者やドメインエキスパートを含むチーム全体の共通言語として定義され、チーム内の会話、ドキュメントやコードに至るまで統一的に使用される言葉 ※ドメイン駆動設計 DDD ***2016/06/23*** ### コンポーネント による パッケージング p.357 【今までのアドバイス by アンクルボブ】 ・SOLID原則 ・REP(再利用・リリース等価の原則) ・CCP(閉鎖性共通の原則) ・CRP(全再利用の原則) c.f.[# 第13章 コンポーネントの凝集性](#第13章-コンポーネントの凝集性)![](https://i.imgur.com/pHt1sDh.png) この本では、コンポーネントとはデプロイできる最小の単位を指す。 REPの弱点とは? 【厳格なクリーンアーキテクチャ】 ・依存性の矢印は下位に向かう ・書くレイヤーは次の下位レベルのレイヤーにのみ依存 →非循環依存グラフ 例外:5 CQRS(コマンドクエリ責務分離) ※DB設計は最後に、とよく言われるが、実務ではビジネスロジック以前にDBに手を出すことも多い(テーブル・DB設計など)(スクラムは特に?(スクラムマスターは大事)) [12 factor apps](https://12factor.net/ja/) ・静的解析ツール(NDepend、Structure101、 Checkstyle など)(VScodeに入っている?) アンクルボブ「コンポーネントとはデプロイできる最小の単位」 Simon Brown「関連する機能をインターフェイスの向こう側に閉じ込め、アプリケーション等の実行環境に置いたもの」 (余談) モノリスとマイクロサービスについて マイクロサービスをコンテナ(K8sなど)でまとめるとリリースに時間がかかる 一方、モノリスで一度にまとめて作ると一度にデプロイしないといけない単位が大きすぎる ☆彡2022/07/07 ☆彡 七夕 次回 ### 悪魔は実装の詳細に宿る おまけはアンクルボブの自伝でした アンクルボブがアンクルボブになった由来が書いてあるぞ ~~レーザーカットまで~~ 【LT会の計画】 (ゆりえさん、ねこさいん) ・SOLIDの順守 ・クリーンアーキテクチャの概要 ・ビジネスレイヤーに合わせる ・(ゆりえさん)アジャイルとSOLIDの関係 ・(しのさん)SpringでSOLIDをいい感じにできる