銀行員からのRailsエンジニア

銀行員からのRailsエンジニア

銀行員から転身したサービス作りが大好きなRailsエンジニアのブログです。個人で開発したサービスをいくつか運営しており、今も新しいサービスを開発しています。転職して日々感じていること、個人開発サービス運営のことなどを等身大で書いていきます。

【技術書メモ】オブジェクト指向設計実践ガイド 〜毎週アウトプットチャレンジ⑥〜

毎週 1冊技術書を読んでブログでアウトプットするチャレンジの第6弾ですー!

今回は、オブジェクト指向設計実践ガイド を読みました。

オブジェクト指向設計についてRubyで解説している名著です。

f:id:ysk_pro:20180826134302j:plain

はしがき

第1章 オブジェクト指向設計

  • オブジェクト指向設計では、世界をあらかじめ決められた手続きの集まりと考えるのではなく、オブジェクト間で受け渡されるメッセージの連続としてモデル化している
  • オブジェクト間の相互関係はオブジェクト間で受け渡されるメッセージであり、正しいメッセージを届けるには、メッセージの送り手が受け手のことを知っている必要がある。この依存関係がプログラムの変更を困難にしており、オブジェクト指向設計は依存関係を管理することでプログラムの変更を容易にしている
  • オブジェクト指向設計で最も良く知られているSOLIDという5つの原則
    • 単一責任(Single Responsibility)
    • オープン・クローズド(Open-Closed)
    • リスコフの置換(Liskov Substitution)
    • インターフェース分離(Interface Segregation)
    • 依存性逆転(Dependency Inversion)

第2章 単一責任のクラスを設計する

  • コードの変更が簡単であることの定義
    • 変更が副作用をもたらさない(見通しが良く、コード変更の影響が明白)
    • 要件の変更が小さければコードの変更も小さい
    • 既存のコードが簡単に再利用できる
  • クラスは単一の責任を持つべき:2つ以上の責任を持つクラスは簡単に再利用できない
  • クラスが単一責任かどうかを見極めるには、一文でクラスを説明してみる。「それと」や「また」が含まれていれば責任は2つ以上ある
  • メソッドも、クラスのように単一の責任を持つべきで、その理由や見極め方はクラスと同様である

第3章 依存関係を管理する

  • 一方のオブジェクトに変更を加えた時、他方のオブジェクトも変更せざるを得ないおそれがあるならば、片方に依存しているオブジェクトがある
  • オブジェクトが次のものを知っている時、オブジェクトには依存関係がある
    • 他のクラスの名前
    • メッセージが要求する引数
    • それら引数の順番
  • 依存関係の管理で鍵となるのは、依存の方向を制御すること。自分より変更されないものに依存することが問題解決の方法である

第4章 柔軟なインターフェースをつくる

  • インターフェースとは、クラス内のメソッドで、どのように何を外部に晒すかを説明するもの
  • パブリックインターフェースを作り上げるメソッドの特性
    • クラスの主要な責任を明らかにする
    • 外部から実行されることが想定される
    • 気まぐれに変更されない
    • 他者がそこに依存しても安全
    • テストで完全に文書化されている
  • プライベートインターフェースの特性
    • 実装の詳細に関わる
    • 他のオブジェクトから送られてくることは想定されていない
    • どんな理由でも変更され得る
    • 他者がそこに依存するのは危険
    • テストでは言及さえされないこともある
  • シーケンス図を使うことで、様々なオブジェクトの構成やメッセージ受け渡しの体系を簡潔に実験できる。シーケンス図は思考を明確にし、他の人と共同作業したり意思疎通したりするための手段となる

第5章 ダックタイピングでコストを削減する

  • ダックタイプはいかなる特定のクラスとも結びつかないパブリックインターフェースであり、クラスをまたぐインターフェースはアプリケーションに大きな柔軟性をもたらす
  • ダックタイプによって型付けされたオブジェクトは、そのクラスよりもその振る舞いによって定義される。ダックタイプという名前は、もしオブジェクトがダックのように鳴き、ダックのように歩くならば、そのクラスが何であれそれはダックであるという表現に由来する

第6章 継承によって振る舞いを獲得する

  • 承継とは、根本的にはメッセージの自動委譲の仕組みである。あるオブジェクトが受け取ったメッセージに応答できなければ、他のオブジェクトにそのメッセージを委譲するという関係
  • 未知のメッセージはスーパークラスの階層構造をさかのぼって委譲されていく。サブクラスとはスーパークラスのパブリックインターフェースを全て持っていると想定されるだけでなく、そのインターフェースに定義されるどのメッセージにも適切にレスポンスを返すことが求められる

第7章 モジュールでロールの振る舞いを共有する

  • オブジェクトが応答できるメッセージには次の4種類が含まれる
    • 自身が実装するメッセージ
    • 自身より上の階層のすべてのオブジェクトで実装されるメッセージ
    • 自身に追加されるすべてのモジュールで実装されるメッセージ
    • 自身より上の階層のオブジェクトに追加されるすべてのモジュールで実装されるメッセージ

第8章 コンポジションでオブジェクトを組み合わせる

  • コンポジションとは、組み合わされた全体が単なる部品の集合以上となるように、個別の部品を複雑な全体へと組み合わせること
  • コンポーズされたオブジェクトは、新たな組み合わせへと簡単に再編成できる、シンプルで分離したエンティティから構成される傾向にある

第9章 費用対効果の高いテストを設計する

  • 変更可能なコードを書くためには、価値の高いテストを書く能力が求められる。テストにより自信を持って絶えず継続的にリファクタリングができる
  • 良いテストは、コードへの変更によってテストの書き直しが強制されないように書かれている
  • テストは唯一信用できる設計の仕様書となる
  • テストはオブジェクトの境界に入ってくるか、出ていくメッセージに集中すべき。受信メッセージはその戻り値の値の状態がテストされるべきで、送信コマンドメッセージは送られたことがテストされるべきである 

おわりに

ここまで読んでいただきありがとうございます。

オブジェクト指向、難しいですね。

この本を繰り返し読んでオブジェクト指向設計を身につけていきましょう!

次からはSQLの本を読んでいく予定です。

来週も頑張ります!