Robert C. Martin「Clean Architecture 達人に學ぶソフトウェアの構造と設計」2017/9/17
2017/9/17
https://gyazo.com/a02d73583e818a4e0812fbc940048457
Clean Architecture 達人に学ぶソフトウェアの構造と設計 | Robert C.Martin, 角 征典, 高木 正弘 |本 | 通販
Clean Architecture: A Craftsman's Guide to Software Structure and Design (Robert C. Martin Series) | Martin, Robert |本 | 通販
Clean Architecture 達人に学ぶソフトウェアの構造と設計【委託】 - 達人出版会
Robert C. Martin「Clean Architecture 達人に学ぶソフトウェアの構造と設計」角征典、髙木正弘譯 2018
Clean Coder Blog
クリーンアーキテクチャ(The Clean Architecture翻訳) | blog.tai2.net
抽象度ではなくて、不安定な code が安定した code に依存する、安定した code が不安定な code に依存しない (依存してゐたら安定でなくなる)、なぜなら software の変更しやすさは software の構造ではなく (裏で實はかういふ事情があって、と言ふべきでない) 變更の scope に比例するべきだから、といふのが clean architecture の全てで、その爲に使へる手法が色々あるね (code のメトリクスも、依存關係逆轉の原則 (DIP) も、use case も、臨機應變に使へる便利な tool) と紹介されてゐる。と私は理解してゐる。そして安定性と抽象度は相關が高い (安定度・抽象度等價の原則 (SAP))。何が安定してゐるかは architect が考へるべき事、それが仕事
software architecture の目的は、求められる system を構築・保守するために必要な人材を最小限に抑へることである。
構造 (architecture) の價値 > 振る舞ひの價値
自信過剩
「あとで clean にすればいいよ。先に市場に出さなければ!」
開發者たちはさうやっていつもごまかす。だが、あとで clean にすることはない。市場からの pressure は止まらないからだ。「先に市場に出さなければ」といふことは、後ろに競合他社が大勢ゐるといふことである。競合他社に追ひ拔かれないためには、これからも走り續けるしかない。
その結果、開發者は mode を切り替へることができない。次の機能、また次の機能、またまた次の機能を追加することになり、code を clean にすることまで手が囘らない。そして、崩壞が始まる。生產性が zero に近づいていく。
福島真人「學習の生態學⸺リスク・實驗・高信賴性」2010/8/4.icon福島真人「學習の生態學⸺リスク・實驗・高信賴性」2010/8/4
事實は、短期的にも長期的にも、 崩壞した code を書くはうが clean な code を書くよりも常に遲い。
自信過剩による再設計は、元の project と同じやうに崩壞する。
構造の價値 (重要) > 振る舞ひの價値 (緊急)
完ぺきに動作するが、變更できない program を與へられたとする。要件が變更されると機能しなくなる。修正することもできない。したがって、この program はいづれ役に立たなくなる。
動作しないが、變更が簡單な program を與へられたとする。要件が變更されても修正は可能なので、動かし續けることができる。したがって、この program はこれからも引き續き役に立つ。
software を soft に保つ
stakeholder が機能を變更したいと思へば、その變更は簡單にできるやうになっておくべきだ。變更の難易度は、變更の形狀ではなく、變更の scope に比例しなければいけない。
できるだけ長い期間、できるだけ多く選擇肢を殘す
「system を適切に動作させること」ではない
方針を詳細から守り、詳細の決定を延期。留保する
詳細の例 : DB。Web server。API 形式。framework。切り離し方式
database は詳細
Web は詳細
framework は詳細
DI framework は詳細
標準 library は詳細
方針
entity (最重要 business data + 最重要 business rule)。system が自動化されてゐなくても存在する
單一性 (oneness)・同一性 (sameness)・範疇 (category)
/kawasima/イミュータブルデータモデル
常に valid にする。invalid な entity を生成しない
/kawasima/Always-Valid Domain Model
次點は use case。application 固有の business rule
進化的 architecture
cf. 進化的計算 - Wikipedia
Neal Ford, Rebecca Parsons, Patrick Kua「進化的アーキテクチャ」島田浩二譯 2018
$ \ne順應
動的平衡への進化可能 > 靜的平衡への豫測可能
境界線を引く
不要な依存を取り除く
決定を可逆にする
對稱性
可換性
在庫を減らす
大野耐一「トヨタ生產方式⸺脫規模の經營をめざして」1978/5/1大野耐一「トヨタ生產方式⸺脫規模の經營をめざして」1978/5/1.icon
實驗
architecture 適應度函數 (architecture fitness function)
architecture の適應度函數は、ある architecture 特性がどの程度滿たされてゐるかを評價する客觀的な指標を與へる。
ある architecture 特性または architecture 特性の組み合はせについて、客觀的な整合性評價を行ふための何らかの仕組み。
architecture 特性 : -ility (〜性)
trade-off
monitoring 驅動開發 (MDD)
監視は繼續的な test
繼續的 delivery & deploy (CD)
例
循環依存
循環的複雜度 (cyclomatic complexity)
循環的複雑度 - Wikipedia
$ M:={\rm Edge}-{\rm Node}+2P={\rm ClosedLoop}+1
槪ね 10 以下がよい
主系列からの距離
安定度・抽象度等價の原則 (SAP)
layer 統制
Unit test your Java architecture - ArchUnit
BenMorris/NetArchTest: A fluent API for .Net that can enforce architectural rules in unit tests.
Netflix/SimianArmy: Tools for keeping your cloud operating in top form. Chaos Monkey is a resiliency tool that helps applications tolerate random instance failures.
Conformity Monkey、Security Monkey、Janitor Monkey
SQuBOK
SQuBOK(R)-ソフトウェア品質知識体系ガイド/日科技連|ソフトウェア品質|SQiP研究会
software architecture とは、境界線 (boundary) を引く技藝である。
←→結合 (coupling)
software は基盤より長壽命
software は消耗しないが、firmware や hardware は時代遲れになる。その結果、software の變更が必要になる。
software は消耗しないが、管理できていない firmware や hardware の依存關係により、software が內部から破壞される可能性がある。
基盤 : 物理→infrastructure→hardware→firmware→OS→VM→framework
software とは hardware より後に來るもの、hardware とは software より前に來るもの
software は hardware の囘路を書き換へて別の機械として動作させる
依存關係逆轉の原則 (DIP) により抽象 (software) に 詳細 (hardware) が依存するべきである
hardware 抽象化 layer (HAL ; hardware abstraction layer)
OS 抽象化 layer (OSAL ; operating system abstraction layer)
data は logic より長壽命
Clojure.iconREPL 驅動開發
Erlang.iconhot code swap
programming paradigm
構造化 programming
構造化 programming は、直接的な制禦の移行に規律を課すものである。
構造化プログラミング - Wikipedia
ジャクソンの構造化プログラミング - Wikipedia
構造化定理 - Wikipedia
ミルズの構造化プログラミング - Wikipedia
源流 (手本) : Pascal
architecture としての關心事 : componet の分離
構造的歸納法による證明
構造的帰納法 - Wikipedia
科學的な、test 可能性
OOP (object 指向 programming)
object 指向 programming は、閒接的な制禦の移行に規律を課すものである。
オブジェクト指向プログラミング - Wikipedia
源流 (手本) : Smalltalk
architecture としての關心事 : 機能
polymorphism (多相性)
多相型
依存關係を制禦し逆轉できる
獨立して deploy できる
獨立して開發できる
函數型 programming
函數型 programming は、代入に規律を課すものである。
直接的な data の變更に規律を課す
関数型プログラミング - Wikipedia
源流 (手本) : LispClojure.icon。MLOCaml.icon。Wolfram 言語Wolfram 言語.icon。APLJ.icon。Joy (tacit programming : Point-free, Concatenatives & J)
こんなんが一つの paradigm の訣無いぢゃん…
MLOCaml.iconは證明に有利なのが產まれた理由だから、函數型 paradigm でない RustRust.iconと同じ範疇だよな
architecture としての關心事 : data 管理
event sourcing
閒接的な data の變更に規律を課す
RAII (resource acquisition is initialization)
affine 型
STM (software transactional memory)
ソフトウェアトランザクショナルメモリ - Wikipedia
Ref。Atom : /funisaya/Clojure の deref 可能な値
主に外部 resource に關して destructor を呼ぶ RAII
RAII - Wikipedia
JavaJava.iconの try-with-resources。C# の using。PythonPython.iconの with
RubyRuby.icon の block 引數
$ \ne.
C の free
try {} finally {}
GoGo.iconの defer
評價順序に規律を課す?
論理 programming
論理プログラミング - Wikipedia
源流 (手本) : Prolog
これは制禦か?
Future[T]
原則
coding level
coding は製造作業ではなく設計作業。設計書は source code
coding は設計作業だから試行錯誤する
民藝は設計と製造を區別しない
source code は製造過程 (compile) と密結合
architecture は設計の設計
自己言及の自己言及
module level (SOLID)
SOLID - Wikipedia
單一責任の原則 (SRP) (single responsibility principle)
Conway の法則から導かれる當然の歸結。個々の module を變更する理由がたったひとつだけになるやうに、software system の構造がそれを使ふ組織の社會的構造に大きな影響を受けるやうにする。
module を變更する理由はたったひとつだけであるべきである。
module はたったひとりの user や stakeholder に對して責務を負ふべきである。
module はたったひとつの actor に對して責務を負ふべきである。
組 (法・市・組)
component level では、閉鎖性共通の原則 (CCP)
architecture level では、「architecture の境界」を作るための「變更の軸」
開放 - 閉鎖の原則 (OCP) (open-closed principle)
開放/閉鎖原則 - Wikipedia
Bertrand Meyer が 80 年代に廣めた原則。software を變更しやすくするために、既存の code の變更よりも新しい code の追加によって、system の振る舞ひを變更できるやうに設計すべきである。
software の構成要素は擴張に對しては開いてゐて、修正に對して閉じてゐなければならない。
抽象に依存する
plugin
aspect 指向 programming (AOP)
Liskov の置換原則 (LSP) (Liskov substitution principle)
Barbara Liskov が提唱した有名な派生型の定義。1988 年に誕生。要するに、交換可能な parts を使って software を構築するなら、個々の parts が交換可能となるやうな契約に從はなければいけないといふこと。
契約に依る設計 (DbC)
interface 分離の原則 (ISP) (interface segregation principle)
software を設計する際には、使ってゐないものへの依存を囘避すべきだといふ原則。
component level では、全再利用の原則 (CRP)
依存關係逆轉の原則 (DIP) (dependency inversion principle)
制禦の反轉 (IoC。inversion of control)
制御の反転 - Wikipedia
上位 level の方針の實裝 code は、下位 level の詳細の實裝 code に依存すべきではなく、逆に詳細側が方針に依存すべきであるといふ原則。
module 閒の抽象化 (禮 (protocol))
例 : interface
coding level では
變化しやすい具象 class を參照しない。
變化しやすい具象 class を繼承しない。
具象函數を override しない。
變化しやすい具象を名指しで參照しない。
component level では、安定依存の原則 (SDP) + 安定度・抽象度等價の原則 (SAP)
architecture level では、依存性の rule
依存性の注入 (DI)
component level
component : deploy の單位。動的 link
Library を作ると云ふ開發手法
https://gyazo.com/d9164220c5112dc6a23dfd736bc4c1cc
再利用・release 等價の原則 (REP) (reuse / release equivalence principl)
再利用の單位と release の單位は等價になる。
ひとつの component を形成する class や module は、まとめて release 可能でなければいけない
閉鎖性共通の原則 (CCP) (common closure principle)
同じ理由、同じ timing で變更される class を component にまとめること。變更の理由や timing が異なる class は、別の component に分けること。
component を變更する理由が複數あるべきではない
變更の種類が似てゐる class をひとつの component にまとめる
開放 - 閉鎖の原則 (OCP) に於ける閉鎖の理由は component 內で同じでなければならない
凝集度 (cohesion)
凝集度 - Wikipedia
Programming complexity - Wikipedia
module level では、單一責任の原則 (SRP)
同じ timing、同じ理由で變更するものはひとまとめにすること。變更の timing や理由が異なるものは別々に分けること。
全再利用の原則 (CRP) (common reuse principle)
componet の user に對して、實際には使はないものへの依存を强要してはいけない。
module level では、interface 分離の原則 (ISP)
不要なものには依存しないこと。
非循環依存關係の原則 (ADP) (acyclic dependencies principle)
componet の依存 graph 循環依存があってはいけない。
component の依存關係を管理する
component 圖
code:components の依存關係.mmd
flowchart TB
View --> Presenter
Presenter --> Interactor
Authorizer --> Interactor
Controller --> Interactor
Database --> Interactor
Interactor --> Entity
安定依存の原則 (SDP) (stable dependencies principle)
安定度の高い方向に依存すること。
不安定さ (instability)$ I=\frac{C^e}{C^a + C^e}
I = 0 は最も安定してゐる component
I = 1 は最も不安定な component
fan in$ C^a: 依存入力數。component 內の class に依存している外部の component の數。求心性結合 (afferent coupling)
fan out$ C^e: 依存出力數。component 內にある、外部の component に依存している class の數。遠心性結合 (efferent coupling)
下位 level の component が上位 level の component に依存する
sorce code の依存性は data flow から切り離し、level と結び附けるべきである。
「level」の嚴密な定義は「入力と出力からの距離」である。方針が system の入力と出力から離れてゐれば、それだけ level は高くなる。入力と出力を管理する方針は、system のなかで最下位 level の方針になる。
module level では、依存關係逆轉の原則 (DIP) の一部
安定度・抽象度等價の原則 (SAP) (stable abstractions principle)
component の抽象度は、その安定度と同程度でなければいけない。
抽象度$ A=\frac{m^a}{m^c+m^a}
$ m^c: component 內の class の總數。
$ m^a: component 內の抽象 class と interface の總數。
https://gyazo.com/06e8586df14c0696f4cd569d8da91c80
主系列からの距離 (distance) $ D = |A+I-1|\in\lbrack0,1\rbrack
閾値 (soft limit) を定める。例へば$ D\le 0.1
苦痛 zone になり易いもの : DB schema。java.lang.String 等の具象 utility
module level では、依存關係逆轉の原則 (DIP) の一部
architecture level
DRY (don't repeat yourself) は設計の原則ではない
YAGNI (you aren't going to need it) は設計の原則ではない
部分的な境界を引いておく
分離するが同じ component に置く
strategy。片方だけの境界
facade
connascence
system の全體的な正しさを維持するため、ある component の變更が別の component の變更を必要とする場合、2 つの component は connascent (接續) されてゐる。
https://gyazo.com/7b1edd822a517ccb5da27346c146d163
結合度 (coupling)
結合度 - Wikipedia
clean architecture
その architecture は何と叫んでゐるか?
例
hexagonal architecture
ヘキサゴナルアーキテクチャ(Hexagonal architecture翻訳) | blog.tai2.net
port と adapter
DCI archirecture
DCIアーキテクチャ - Trygve Reenskaug and James O. Coplien - Digital Romanticism
James O. Coplien「パターンに機能と型を取り戻す アジャイルにおいてアーキテクチャを表現するDCI」和智右桂譯 2010
Data, context and interaction - Wikipedia
MVC (model - view - controller)
DCI (data - context - interaction)
data + role
data
何であるか
role
何をするか。algorithm に對應する
OORAM
Object Oriented Role Analysis and Modeling - Wikipedia
Scala.iconの trait
Using Scala Traits Like Abstract Classes | Scala Book | Scala Documentation
code:scala
class Data { }
object Context {
trait Role1 { }
trait Role2 { }
object Interaction {
def doSomething(data1: Role1, data2: Role2) { }
}
}
data1 = new Data with Context.Role1
data2 = new Data with Context.Role2
Context.Interaction.doSomething(data1, data2)
code:scala
class Data { }
object Context {
trait Role1 { }
implicit def dataToRole1(data: Data): Role1 = { }
trait Role2 { }
implicit def dataToRole2(data: Data): Role2 = { }
object Interaction {
def doSomething(data1: Role1, data2: Role2) { }
}
}
data1 = new Data
data2 = new Data
Context.Interaction.doSomething(data1, data2)
context
data に、scenario (use case) の中の role を振り付ける。data を cast に仕立てる
interaction
role の振られた data を、user の想定する algorithm (business rule) に從って動作させる
BCE (boundary - control - entity)
C4 model
The C4 model for visualising software architecture
C4モデル - Wikipedia
mermaidmermaid.icon
C4 Diagrams | Mermaid
system context - container - component - code
level 每の圖
1. context diagrams
2. container diagrams
3. component diagrams
4. code diagrams
要素
persons
software systems
containers
components
relationships
clean architecture
クリーンアーキテクチャ(The Clean Architecture翻訳) | blog.tai2.net
抽象性の降順。下は上に依存する
企業の business rule : entity
application の business rule : use case
interface adapter : controller | presenter | gateway
framework と driver : device | Web | UI | 外部 interface | DB (ORM)
Mark Richards、Neal Ford「ソフトウェアアーキテクチャの基礎――エンジニアリングに基づく体系的アプローチ」島田浩二譯 2022
layered architecture
pipeline architecture
microkernel architecture
plugin
service-based architecture
event 驅動 architecture
space-based architecture
MnesiaErlang.icon
DatomicClojure.icon
HashiCorp ConsulHashiCorp Consul.icon
orchestration 驅動 service 指向 architecture
KubernetesKubernetes.icon
microservice architecture
關心事の分離
framework 非依存
test 可能
humble object
例 : presenter に對する view。test しづらい view を控へ目 (humble) に保つ
UI 非依存
database 非依存
外部 agent 非依存
microservice
我々が學んだのは、architecture の境界は service と service の中閒に位置するわけではないといふことだ。architecture の境界は、service を橫斷することで、component に分割してゐるのである。
橫斷的關心事 (cross cutting consern)
architecture 量子
高度な機能的凝集性と同期的な connascence を持つ、獨立して deploy 可能な artifact。
test
Test like a team.
test 驅動開發 (TDD)
test は architecture の最も外側に在る
脆弱な test の問題 (fragile tests problem)
GUI 等の、變化しやすいものに依存しない
test 用 API
application の構造から test の構造を切り離 す
このやうな進化の分離が必要なのは、時閒が經つにつれて、test は具體的かつ個別化する傾向があるからだ。それとは對照的に、production code は抽象的かつ一般化する傾向がある。構造的結合が强いと、かうした進化の分離が妨げられる。
ADR (architecture decision records)
#藏書