Open19

良いコード / 悪いコードで学ぶ設計入門

ほったほった

第1章 悪しき構造の弊害を知覚する

よくない構造

  • 命名が意味をなしておらず、理解が困難
  • 条件分岐が複雑で見通しが悪い
  • データと計算ロジックが分離され、低凝集になっている
ほったほった

関数型で書いてるため低凝集になってしまってる
関数型で対策することは可能か?ある程度関数で扱った方がいいのか?

ほったほった

第2章 設計の初歩

  • 意図が伝わる名前をつける
  • 変数をイミュータブルにして使い回さない
  • 処理ごとにメソッド化する
  • 関係するデータとロジックをクラスにまとめる
ほったほった

第3章 クラス設計 - すべてにつながる設計の基礎 -

  • 変数とメソッドをまとめてクラス単体で動作するようにする
  • インスタンスを不変な値として扱う
  • コンストラクタでバリデーションを行い、不正な値を弾く
ほったほった

関数型で書いてるとコードが散らばって重複が増えたりする

ほったほった

不変の活用 -安定動作を構築する-

再代入可能だとその値が今何を表してるのかわからなくなる
→ 大原則としてconstを使って不変な値として扱う

可変な値を使い回すと、別のところで行った変更が意図しない形でバグを起こす

副作用: 関数が引数を受け取り値を返す以外の外部の状態を変更すること

関数の影響範囲を限定する

不変と可変の使い分け

デフォルトは不変

可変にしてもいい場面

  • パフォーマンスが落ちる場合に可変にする
    • データ量が多いとき、新しいインスタンス作成に時間+メモリを消費するため
  • スコープが局所的な場合
ほったほった

reactでもコンポーネントに渡すタイミングで値を変えるのは良くないかも
コンポーネントに渡すためにfilterやmapをする場所を決めた方が意図しないタイミングでの変更が減りそう

ほったほった

第5章 低凝集 -バラバラになったモノたち-

低凝集
モジュール内における、データとロジックの関係性の強さを表す指標

低凝集に陥る原因

  • クラスメソッドの誤用
    • クラスメソッドはインスタンス変数を操作しないときに使用する
  • コンストラクタがさまざまな目的で使用される
    • クラスメソッドとして目的別の初期化ロジックを作成することでコードをひとまとめにできる(ファクトリメソッドを使う)
  • 共通処理のロジックで引数の値を変更する(副作用を起こす)
  • 引数が多すぎる
    • プリミティブ型を使いすぎない
  • メソッドチェインを誤用する
    • セッターメソッドを使用しする
    • デメテルの法則(使用するオブジェクトの内部を知るべきではない)
ほったほった

コンストラクタがさまざまな目的で使用される

これ、同じ目的のインスタンスを複数箇所で作っていて、その初期化時の引数を変える場合変更漏れが起きるからダメ

ほったほった

コードの重複が起きて保守性が低くなるのがダメ
共通の処理には名前をつける

ほったほった

第6章 条件分岐 -迷宮化した分岐処理を解きほぐす技法-

条件分岐で発生しうる問題・対策

ネストが多くなる+ネストないの行数が多くなることで見通しが悪くなる

対策

  • 早期return
    • ネストが浅くなって見通しが良くなる
    • 条件と実行のロジックを分離できる

switchを使って同じ条件を複数箇所で使い回す(switch文が重複する)とき、追加漏れが発生する

対策

  • 単一責任選択の原則(同じ条件式の条件分岐を一箇所にまとめる)
  • クラスで呼び出しロジックを統一する(ポリモーフィズム、ストラテジーパターン)

フラグ引数を使用することで何が起きるのかを予測しづらくする

対策

  • 分岐後の機能ごとにロジックを分割する
  • ストラテジーパターンでロジックを切り替える
ほったほった

単一責任選択の原則を満たすために、オブジェクト or JSONの設定を書くのが良さそう

class x implementsでそれぞれのクラスを作成して管理するのもあり(オブジェクト指向なら)
tsでも似たような書き方はできる

ほったほった

プリミティブ値をできるだけ使わず、値のオブジェクトとして扱った方がいいらしい
値はクラスで扱う方がいいのか?tsのオブジェクトで対応可能なのか?

ほったほった

似たような条件分岐がある時、ポリシーパターン
各条件を判定するロジックを作り、必要な条件だけの配列を用意する

ほったほった

最後の内容、displayTypeで出し分けてるのにも応用できそう

ほったほった

第7章 コレクション -ネストを解消する構造化技法-

配列やリストに生じる悪魔について

自分でコレクション処理を記述しない
jsのforEachやmap、reduce

配列に対する処理は低凝集にらなりやすい
ファーストクラスパターンで対策
配列に対する処理をまとめかクラスを作り、インスタンス変数に配列を入れておかげ

ほったほった

使うとしたら、SSRで取得したデータをクラスのコンストラクターにぶち込んでって感じかな?
基本配列のデータが変わらないことを想定するならそれでいい
websocket使ってリアルタイムでデータを取得する場合はクラスだと再レンダリング置かない可能性があるからそこの対策は必要そう

ほったほった

第8章 密結合 -絡まった解きほぐせない構造-

結合度:モジュール間の依存の度合いを表す指標
責務:ある関心事について、正常に動作する責任

責務が考慮されていないとロジックの置き場所がバラバラになる

単一責任の原則:クラブが担う責任は、たったひとつに限定すべき
責任は誰がその責任を負うべきか適用範囲とセットになっている

DRYの原則:繰り返しを避けよ
すべての知識はシステム内において、単一、かつ明確な、そして信頼できる表現になっていなければならない

ほったほった

共通化しすぎるのも良くないらしい
概念として違うものの場合共通化しない(条件分岐が発生しまくる場合)