# Clean Architecture 第III部 第7章 単一責任の原則 読書会#7 ###### tags `book` ## 概要 |項目|内容| |-|-| |開催日|2021/05/23| |開始時間|13:00| |終了時間|18:00| |メンバー|nonx,B| *** ## 感想・気づき・疑問 ### 設計の原則 #### nothing P.77 > **SOLID原則**は、**関数やデータ構造をどのようにクラス[^1]に組み込む**のか、そしてクラスの**相互接続をどのようにするのか**といったことを教えてくれる。 [^1]:ここでいうクラスは単にいくつかの機能やデータをとりまとめたものを指していて、オブジェクト指向ソフトウェアにしか適用しないわけではない。P77 Line5 >**SOLID原則の誕生** >1980年代後半から2000年代初期かけて著者がコミュニティで議論しまとめた原則。 >2004年頃、Michael Feathersから「これらの原則の並び順を変えれば、頭文字をSOLIDと読めるのでは?」というメールが届いたことが誕生の発端。 **Michael Feathersとは** ![face](https://theagilerevolution.files.wordpress.com/2018/10/mfeathers.jpg) https://michaelfeathers.silvrback.com/bio >Michael Feathers is the founder and Director of R7K Research & Conveyance, a company specializing in software and organization design. Michael is also the author of the book Working Effectively with Legacy Code (Prentice Hall, 2004). **ボブおじさんCマーティン** ※2014年 ブログでSRPに言及[ブログ](https://blog.cleancoder.com/uncle-bob/2014/05/08/SingleReponsibilityPrinciple.html) ※2017年 Clean Architecture >**SOLID原則の目的 P77** >* 変更に強いこと >* 理解しやすいこと >* コンポーネントの基盤として、多くのソフトウェアシステムで利用できること >**SOLID原則 P78** >* 単一責任の原則(SRP: Single Responsibility Principle) >* オープン・クローズド原則(OCP: Open-Closed Principle) >* リスコフの置換原則(LSP: Liskov Substitution Principle) >* インターフェイス分離の原則(ISP: Interface Segregation Principle) >* 依存関係逆転の原則(DIP: Dependency Inversion Principle) *** ### SRP:単一責任の原則 P.81 *** #### nothing **定義の変遷** 1. 初期 > **モジュールを変更する理由はたったひとつだけであるべきである。** 2. 中期:変更する理由という文言が曖昧であったため変更 >**モジュールはたったひとりのユーザやステークホルダーに対して責務を負うべきであ** 3. 後期:たったひとりのユーザやステークホルダーは現実を反映していないため変更 >**モジュールはたったひとつのアクターに対して責務を負うべきである。** **用語** - アクター: 変更を望む人たちをひとまとめにしたグループ - モジュール: いくつかの関数やデータをまとめた凝集性のあるもの。 具体的にはソースファイルや設定ファイルを指している。 - [凝集性(凝集度)](https://ja.wikipedia.org/wiki/%E5%87%9D%E9%9B%86%E5%BA%A6) >凝集度は次のような場合に低下する: >クラスの責任範囲(メソッド群)に共通性がほとんどない。 メソッドが様々なことを行い、しばしば粒度の粗いデータや全く関係のないデータ群を扱う。 *** #### 症例1:想定外の重複 C-level:経営幹部レベル CXXで表現される役職 例:CTO **時系列1** Employeeクラスが下記メソッドを保持していた。 |所属クラス |メソッド | |---------------|----------------| |Employee |caluculatePay()| |Employee |reportHours() | |Employee |save() | **時系列2** caluculatePay()の中で所定労働時間の計算を行っていた reportHours()の中で所定労働時間の計算を行っていた なので、共通のプライベートメソッドを作成した。 regularHours()が作成された。 **時系列3** caluculatePay()に仕様変更発生。 regularHours()の仕様が変更された。 reportHours()に影響があったが、開発者はcaluculatePay()のみ試験を行いリリース。 デグレが発生した。 **どうすればよかったのか?** アクターの異なるコードは分割するべきであることを示している。 下記がアクターとメソッドの関係となっている。 |アクター |メソッド | |---------------|----------------| |経理部門 |caluculatePay()| |人事部門 |reportHours() | |データベース管理者|save() | *** #### 症例2:マージ **時系列1** Employeeクラスが下記メソッドを保持していた。 |所属クラス |メソッド | |---------------|----------------| |Employee |caluculatePay()| |Employee |reportHours() | |Employee |save() | caluculatePay()とreportHours()とsave()それぞれに仕様変更が発生 それぞれのメソッドは、別のチームが開発していた。 それぞれ試験を行った後、マージを行った。 この時コンフリクトが発生。 コンフリクト時に複雑に絡み合っていたソースコードのマージに失敗した。 デグレの発生。 **どうすればよかったのか?** **アクターの異なるコードは分割するべき** *** #### 解決策 クラスの分割 関数の分割 Facadeパターンの利用などが具体的な対応として示されている。 *** #### まとめ *** ## ふりかえり ### YWT #### Y: やったこと - a #### W: わかったこと - a #### T: 次にやること - a *** ### KPT #### Keep - 事前に書いておくことは時短になり有効 - 事前準備パライムの導入 - 進行の秩序が生まれた。 - 分からないことは分からないので、文章から読み取れることの範囲で十分わかることを分かっていく姿勢 #### Probrem - アーキテクチャの**境界**などのよくわからない言葉や概念を現状放置している状態。 - プログラムをダイクストラにはなぜか証明できなかったのか? - クラス、モジュール、コンポーネントあらゆるレベルで構造化プログラミングの制限しているがその制限のルールはどのようなものか? - 眠いのはやめたい。 #### Try - 疑問点のリスト化をしてすぐにアクセスして解消できるような仕組み - KPTを次に持ち越すことで一旦対応 - 運動します。 *** ### Fun-Done-Leanrn #### Fun: - a #### Done: - a #### Learn: - a 速度 満足度 進め方 http://prof.mau.ac.ir/images/Uploaded_files/Clean%20Architecture_%20A%20Craftsman%E2%80%99s%20Guide%20to%20Software%20Structure%20and%20Design-Pearson%20Education%20(2018)[7615523].PDF https://blog.cleancoder.com/uncle-bob/2014/05/08/SingleReponsibilityPrinciple.html