クリーンアーキテクチャ読書会の感想 #techplaygirls

クリーンアーキテクチャ 読書会 with ほくりんさん、Chihiro さんが終了しました。その感想です。

  • 2021/10-2021/03
  • 9:00 - 12:00 ぐらい
  • 毎週 土曜日

クリーンアーキテクチャの概要

開発における私たちのユートピア、すなわち開発メンバーを増やすことなく一定のスピードで開発し続けることができる世界、最小限のコストで最大限の柔軟性を発揮できる世界を実現するために良い設計が必要です。
良い設計とは?それはコードが入出力からの距離ごとにレベル分けされており、入出力に近いものはレベルが低く、遠いものはレベルが高い。そして SOLID 原則をアーキテクチャにも適用し、レベルごとに境界線を引き依存度を減らすこと、またレベルごとの依存関係は必ずレベルの高い方に向かせることで変更が及ぼす影響は最小限にし、レベルの低い更新は決定を遅らせることができる状態のこと。

良い設計とは?

優れたソフトウェアの設計の目的

求められるシステムを構築・保守するために必要な人材を最小限に抑えることである。

設計の品質は計測できる。常に必要な労力が低く保たれているなら、その設計は優れているし、逆にリリースごとに労力が増えるなら、その設計は優れていない。

ソフトウェアを「ソフト」に保つ

マシンの振る舞いを簡単に変更したくないとき、それを「ハード」ウェアと呼んでいる。すなわち、ハードと対比した「ソフト」ウェアは簡単に変更できなければならない。

変更の難易度は、変更の形状ではなく変更のスコープに比例させる

ソフトウェア開発者は、「四角い」ペグを「丸い」穴に打ち込まなければいけないような気持ちになることがよくある。

漫画にした。

f:id:meikotan:20210405123026j:plain
変更の難易度は、変更の形状ではなく変更のスコープに比例させないと辛い

「穴の形状を変えたのはそっちだろ!?😡」と言いたくなるんだけど、そもそもこういった特定の「形状」にとらわれるアーキテクチャにしない方が実用的。

選択肢を残しておく

変更可能な状態にして決定を遅らせたい。これだ!ってものが見つかるまで重要ではない詳細は決めない。決定を遅らせた分、適切に作るための情報が数多く手に入る。形状に依存しないと同じような意味。

SOLID 原則

SOLID 原則のポイントとアーキテクチャに適用する場合のポイントが書かれていた。SOLID 原則ってクリーンアーキテクチャで提唱されてるのかと思ってたけど間違ってたわ。

原則を知ってるからって、すぐには実践できるわけじゃないんだけど。コードを書く上での基準として、すべきであるっていう事は常に心に留めておきたい。

単一責任の原則

コンウェイの法則(システムを設計する組織は、組織のコミニケーション構造をコピーした構造の設計を生み出す)から導かれる当然の帰結。ここのモジュールを変更する理由がたった1つだけになるように、ソフトウェアシステムの構造がそれを使う組織の社会的構造に大きな影響受けるようにする。

モジュールとは一つのソースファイルのこと。

モジュールはたったひとつのアクターに対して責務を負うべきである。

すなわち、アクターの異なるコードは分割するべき。

組織構造とソースコードの責任範囲って全然関係ないものって考えたけど、むしろ影響を受けるようにした方が良いんだね。自分の書いてるソースコードが本当に一つの責任しか負っていないのか?判断基準が曖昧だったけど、アクターを分離しろ!は分かりやすい基準だと思った。

メモ:他のレベルでの同じような原則

オープン・クローズドの原則

ソフトウェアの構成要素は拡張に対しては開いていて、修正に対して閉じていなければならない。 言い換えれば、ソフトウェアの振る舞いは、既存の成果物を変更せず拡張できるようにすべきである、ということだ。 これこそが、我々がソフトウェアアーキテクチャを学ぶ根本的な理由だ。

本当にそう思う。

オープン・クローズドの原則の目的は、変更の影響を受けずにシステムを拡張しやすくすることだ。目的を達成するために、システムをコンポーネントに分割して、コンポーネントの依存関係を階層構造にする。そして上位レベルのコンポーネントが下位レベルのコンポーネントの変更の影響を受けないようにする。

これがクリーンアーキテクチャの中心部分の考えだし、円の一例もこれのこと。

f:id:meikotan:20210405140519j:plain
The clean architecture (https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html より引用)

インターフェースの役割は2つ

① 上位レベルのコンポーネント保護

上位レベルのコンポーネントは下位レベルの変更の影響を受けてはいけない。そのため、場合によっては制御の流れと逆転した依存関係にする必要があり、インターフェイスを使用して依存関係逆転の原則を適用する。

② 下位レベルのコンポーネント保護

下位レベルのコンポーネントは上位レベルのコンポーネントであっても自分が直接使っていないものにまで依存すべきではない。(上位コンポーネントの内部を知り過ぎてはいけない)下位レベルのコンポーネントが直接使うものだけに依存できるようにインターフェイスを使用し情報隠蔽を行う。

f:id:meikotan:20210408125615j:plain

リスコフの置換原則

リスコフの置換原則 - Wikipedia

これはもうその通りだし、イレギュラーを認め始めると仕組みがどんどん複雑になってくる。

インターフェイス分離の原則

不要なもの(使ってないもの)には依存しないこと。

依存関係逆転の原則

ソースコードの依存関係が具象ではなく、抽象だけを参照しているものが最も柔軟なシステムである。それが難しい場合は、なるべく変化しにくいものへ依存すること。依存したくないのは、変化しやすい具象要素である。

階層ごとの境界を引くために何度も利用される原則。GoFデザインパターン本を並行して読んでたので、この原則の理解が進むに連れて、このパターンはインターフェイスを置くことで依存関係逆転してるなぁということが分かるようになった。

Uncle Bob の講演(2021/01/29)

まるで私たちのために用意されたかのような奇跡的なタイミングで Builders Box by Sansan のイベントに Uncle Bob がきました!!(°▽°) Sansan ありがとう!

講演内容はクリーンアーキテクチャの大まか説明と質疑応答でした。その内容は Sansan のブログを見てください。

印象に残ったことは、以下の質問に対して

よいアーキテクチャは重要な決定を延期させてくれるもの、という点についてはなるほど、と思った。では、延期をした決定はいつすればいいのか? 意志決定の適切なタイミングはいつなのか?

Bob が色んな理由を踏まえながらも「分かるときがくる」って自己確信している雰囲気で、その感覚すごいなぁと思ったし、私に足りない部分でした。めっちゃ自分のこと信じてる感。そういう本人が持ってる空気感を感じれたのはオンラインであっても直接講演を聞けたおかげだし、文字だけじゃない形で話を聞くって大事だよなぁと改めて感じました。

クリーンアーキテクチャ読了後の感想

この本は t_wada さんのツイートで言及されてたのがきっかけで興味を持ち、目次を眺めたときに SOLID 原則について書かれていて読みたくなりました。SOLID 原則はネットの記事でよく見るけどイマイチ理解できてない用語だったので、きちんと学びたいと思ったからです。でも、読み終わった後にこの本で一番印象に残ったのは、1章の「なぜ正しい設計目指すのか?」「どうやって正しい設計と判断するのか?」についての記述です。そこを理解し自分も正しい設計を目指したいと思ったおかげで、SOLID 原則や境界線、一方向の依存関係の重要さがより身に染みた気がします。また、設計について書かれたネットの記事がグッと読みやすくなりました。ただ、この本全体を通して具体例が少なかったので、クリーンアーキテクチャの実例をいくつネットで読んだり、アジャイルソフトウェア開発の奥義を読むのも挑戦したいです。

読書会の感想

読書会メンバーは開発歴はある程度あるってことは一致してるけど、会社は異なっているので視点が幅広く、話していて学びが多かったです。また、日々使っている言語(C#、Typescript、JavaRuby)も全員別々だったので、私が使ってる言語、フレームワークに関しては私が言語化する必要があり、改めて言語化することで気付くことや言語ごとの違いを認識できたりして、とても勉強になりました。そして本当に三人寄れば文殊の知恵で、1人で読んでたら分からないまま素通りしていたことも、深く理解しながら読み進めることができました。感謝。あと3人ともお喋りが好きなので余談もてんこ盛りで笑えました😄

最後に

クリーンアーキテクチャ本の好きな一文を引用して終わりにします。

不完全な知識で運用する可能性があることを認めながら、そうするのが人間であり、人間はそれが得意であることを理解している。我々の弱みよりも強みを生かしてくれる。我々は物を作り、発見する。我々は質問し、実験する。優れたアーキテクチャとは、それが目的地ではなく旅路であること、凍結された成果物ではなく進行形の探索プロセスであることを理解するところから生まれる。

参考