良いコード/悪いコードで学ぶ設計入門
- 悪しき構造の弊害を知覚する
- 設計の初歩
- クラス設計 すべてにつながる設計の基礎
- 不変の活用 安定動作を構築する
- 低凝集 バラバラになったモノたち
- 条件分岐 迷宮化した分岐処理を解きほぐす技法
- コレクション ネストを解消する構造化技法
- 密結合 絡まって解きほぐせない構造
- 設計の健全性をそこなうさまざまな悪魔たち
- 名前設計 あるべき構造を見破る名前
- コメント 保守と変更の正確性を高める書き方
- メソッド(関数) 良きクラスには良きメソッドあり
- モデリング クラス設計の土台
- リファクタリング 既存コードを成長に導く技
- 設計の意義と設計への向き合い方
- 設計を妨げる開発プロセスとの戦い
- 設計技術の理解の深め方
悪しき構造の弊害を知覚する
設計の初歩
クラス設計 すべてにつながる設計の基礎
- 完全コンストラクタ
- 生焼けオブジェクト防止。バリデーション。
- 値オブジェクト
- 値を型として定義。ex.
Money
Date
OrderNumber
PhoneNumber
とか。
- 値を型として定義。ex.
- ストラテジ
- 後の 条件分岐 の章でちょくちょく出てくる。
- ポリシー
- これも。
- ファーストクラスコレクション
- スプラウトクラス
不変の活用 安定動作を構築する
低凝集 バラバラになったモノたち
条件分岐 迷宮化した分岐処理を解きほぐす技法
- interface
switch
とかinstanceof
の乱用を避ける。interface による polymorphism でがんばる。所謂 strategy pattern ね。strategy の切り替えはenum
+ 連想配列 とかで。
- ポリシーパターン
- なんか
Optional
の lifting ぽい感じ。条件をたくさん指定して、全部に合致する場合にこう処理したい、とか、そういう感じのあれ。dicision tree っぽいと言えばそうかも。
- なんか
- フラグ引数を避ける
- かわりに strategy pattern でがんばる。あとは
enum
+ 連想配列 というやつ。
- かわりに strategy pattern でがんばる。あとは
コレクション ネストを解消する構造化技法
- ファーストクラスコレクション
密結合 絡まって解きほぐせない構造
- 影響スケッチ
- dddjava/jig など
- 可視性
public
多すぎは密結合。でもprivate
多すぎも低凝集。
- アンチパターン
- スマート UI
- トランザクションスクリプト
- 巨大 object
- god class
設計の健全性をそこなうさまざまな悪魔たち
- 技術駆動パッケージング
- パッケージ名にレイヤとか入っちゃってるやつ。レイヤは横割りなので、縦割りでどれとどれが関連が強いのか見失うことになる。
名前設計 あるべき構造を見破る名前
- 目的駆動名前設計
- EC サイトにおいて、商品を商品と命名するのではなく、その商品をどう扱いたいのか、という目的を命名に載せる。たとえば、予約品、注文品、在庫品、発送品、など。それぞれの操作・domain に応じた命名をする。
- 良い命名が寄与するのは可読性のみならず、疎結合な設計にとっても不可欠である。
- 存在ベースではなく、目的ベースで考える。
- 要件の認識合わせの時には出てきたのに、実際のソースコード上には出てこない概念は、ほとんどの場合あってはならない。
「このフラグが立っているときの User は要注意会員」
「この行の price は新品価格で、次の行の price は中古価格」
「Ticket クラスは、年齢が60歳以上ならシニア料金用になって、さらに平日なら平日のシニア料金用に変わるんだ」
それぞれ、
- 通常会員クラス、要注意会員クラス
- 新品価格変数、中古価格変数
- 通常料金チケット、シニア料金チケット、平日シニア料金チケット
という風に、クラスを分けたらいかがか。
- 技術駆動命名を避ける。
- 動詞 + 目的語という命名を怪しむ。
- method を適切に配置するとか、引数に取る型を設計するとか、そういうことをすれば method 名が動詞1語で済む場合も多々ある。
コメント 保守と変更の正確性を高める書き方
- ロジックをなぞるだけのコメントをしない。
- 悪い命名をコメントでごまかさない。
- 意図や変更時の注意点をつける。
メソッド(関数) 良きクラスには良きメソッドあり
- instance method は instance variable を必ず使う。
- 基本は純粋関数。
- デメテル
- CQRS を method 単位でも実現する。mutation と値の参照を同時にやらない。
- 引数
- 不変
- フラグ引数はだめ
- null だめ
- 引数の個数は最低限度
モデリング クラス設計の土台
- 目的別にモデリングする
- ex. GitHub の Account settings。Profile/Account/Appearance/Emails/Notifications など、細かく分かれており、目的ごとにモデルが設計されているのがうかがえる。このように、現実世界に存在する物理的な存在と、システム上の存在が、常に1:1ではなく1:多になることもある点に、設計の難しさがあり、注意が必要。
- モデルそのものは、現実世界のモノと対応するというよりは、目的達成のための道具・手段であると解釈すべき。
- だからこそ、目的駆動でモデルに命名をすることが重要。
- 機能性とモデリング
- 「商品購入」というイベントは、実際には「売買契約」という効果を持っているため、そういう命名にすべき。売り手・買い手間でトラブルが起きた場合に、証跡として利用できる可能性があり、機能性を高めることができる。
リファクタリング 既存コードを成長に導く技
- ネスト解消
- 意味ある単位にまとめて、メソッド化する
- メソッド化は何も共通化のためだけの手段じゃない。ある処理の塊に別名をつけて、業務的な意味を明示することにだって使える。そのメソッドを適切な場所に置くことを考えれば、凝集度だって上げられるかもしれない。
- 以上のような変更を加えて、単体テストで品質担保
- ない場合は単体テストを書く(正気ですか?)
- あとは TDD。いつもの。実家のような安心感(実家は本当に安心ですか?)
ただ、TDD は仕様がわかってる状態じゃないとできない。仕様がわからない、でも障害対応しなきゃいけない・リファクタしなきゃいけない、という場合、どうするのです……?
- 仕様分析方法1: 仕様化テスト
- 色んな入力を与えてみて、対応する出力を確認し、それを仕様とする。
- 仕様分析方法2: 試行リファクタリング
- カスのコードを一生懸命読みながら、カスな部分を潰していく。簡単に言えばこれをやる。
- で、そうすると仕様がおのずと見えてくるはず。仕様が見えたらテストコードを書いて、正式にリファクタリングする。試行したコードは merge しちゃだめだよ。
コラムより引用
静的型付け言語に比べ、動的型付け言語のリファクタリングは高難易度です。責務や構造がどうあるべきかを、より深く考える契機になり、自分の設計スキル向上につながっている実感があります。
いや、えらすぎ。「動的型付けはクソ」とか脳死で言ってる自分との格の違いを見せつけられている。
設計の意義と設計への向き合い方
- 設計は何のためにするの? -> 保守性・変更容易性。開発効率の向上。
- レガシーコードによって人の成長が妨げられる
- 人に伝播する
- 高品質設計を納期的な理由で諦めてしまう
- 純粋な開発作業に避ける時間が減る
- 技術的負債は見えない負の要素なので意識しづらい
- なんで見えないの?: 変更容易性の高いコードと、低いコードを用意して、同じぐらいの生産性のチームを用意して、一定期間かけて同じ開発をさせて、それらの生産性を比較して……なんてやってられる企業なんかないわいボケナス。つまりそもそも比較する機会がないってこと。なんかこれ、教育で対称実験しづらい話と似てるね。
- コード分析ツール
- Code Climate Quality
- Understand
- Visual Studio
設計を妨げる開発プロセスとの戦い
- Ancle Bob の 『Clean Architecture』 では、TDD を用いたチームと、テストを書かないチームでの生産性比較が行われ、テストを書いていないチームよりも TDD のチームの方が生産性が高いことが語られている。
- 最低でも、簡単なクラス図ぐらいは書こうね。
- 厳密に設計しすぎない。一発で綺麗に設計なんてできない。
- アンカリング効果: 最初に見たものを基準と思い込む。
- ランチェスターの法則・クープマン目標値: 場の10.9%を占めると、全体に影響する力が出てくる。
設計技術の理解の深め方
- 現場で役立つシステム設計の原則~変更を楽で安全にするオブジェクト指向の実践技法
- リーダブルコード
- リファクタリング 既存のコードを安全に改善する(第2版)
- Clean Code アジャイルソフトウェア達人の技
- レガシーコード改善ガイド
- レガシーソフトウェア改善ガイド
- レガシーコードからの脱却―ソフトウェアの寿命を延ばし価値を高める9つのプラクティス
- エンジニアリング組織論への招待~不確実性に向き合う思考と組織のリファクタリング
- プリンシプル オブ プログラミング
- Clean Archtecture 達人に学ぶソフトウェアの構造と設計
- エリック・エヴァンスのドメイン駆動設計
- セキュア・バイ・デザイン 安全なソフトウェア設計
- ドメイン駆動設計入門 ボトムアップでわかる!ドメイン駆動設計の基本
- ドメイン駆動設計 モデリング/実装ガイド
- ドメイン駆動設計 サンプルコード&FAQ
- テスト駆動開発
- バグハンター2 REBOOT