ravelll の日記

よしなに

オブジェクト指向設計実践ガイド 第7章

7章はモジュールの話。SOLID 原則の L であるリスコフの置換原則が出てきます。


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

  • クラスによる継承はあくまで解法の1つでしかなく、クラスによる継承で解決できる問題には必ず他の解法も存在する

7.1 ロールを理解する

  • 関連のないオブジェクト間で共通の振る舞いをもたせたい場合がある
    • オブジェクトがロール(役割)を担う、という考え方
  • オブジェクトにロールをもたせるとオブジェクト間に依存関係が生じる
    • 振る舞いの共有に発生する依存関係は最小化する
  • Preparer ロールの存在は対応する Preparable モジュールの存在を示唆する
  • ロールを示すコードは1箇所に定義されていつつロールを担いたいどんなオブジェクトからも利用できるようになっているべき
    • モジュールは様々なクラスのオブジェクトが1箇所に定義されたコードを使って共通のロールを担うための完璧な方法
  • どのクラスにどの値を用いるかという知識は Schedule には属さない。属する先は Schedule が名前を確認しているクラス
  • オブジェクトは自分の振る舞いを自分で持つべき
    • オブジェクトAに関心があるとき、オブジェクトAを知りたいがためにオブジェクトBの知識が求められることがあってはならない
  • Schedule にターゲットがスケジュール可能かを聞くのは StringUtils に文字列が空かどうか聞くようなこと
  • モジュールはクラス継承と同じメソッド探索の道筋となるため、コードの書き方やメッセージの解決され方においてクラス継承と同じように振る舞う
  • is-a(クラス継承)と behaves-like-a(モジュールによるコード共有)の違いの重要さ

7.2 継承可能なコードを書く

  • 継承でコードを改善できないか疑うべきアンチパターン
    • オブジェクトが type や category という変数からどんなメッセージを self に送るか決めているパターン
      • 共通のコードは抽象スーパークラスに起き、異なる型をサブクラスとして作る
    • メッセージを受け取るオブジェクトのクラスを確認して送るメッセージを決めてるパターン
      • 受け手になりうるオブジェクトは同じロールを担っている = ダックタイプを見逃している
  • 一部のサブクラスでしか使わないコードはスーパークラスやモジュールに置くべきではない
  • サブクラスはスーパークラスと置換できることを約束する
    • 置換できるのはオブジェクトが期待通りに振る舞うとき、かつサブクラスがスーパークラスのインターフェースに一致するよう"期待される"ときのみ
    • 他のオブジェクトに自身の型を識別させ、自身の扱いや何が期待できるのかを決めさせることはどんなことがあっても許されない
  • リスコフの置換原則
    • システムが正常であるためには派生型は上位型と置換可能でなければならない
  • 継承する側で super を呼び出すのは避けるべき
  • 探索パス上にオブジェクトが多いとメッセージが通過するオブジェクトも増える
  • 階層構造が深いとプログラマーはその頂点と底辺のクラスばかりを理解しがち

7.3 まとめ

  • オブジェクトが共通のロールを担うためには振る舞いを共有する必要があり、それにはモジュールが役立つ
  • モジュールを使うときのコードの書き方は継承を使うときと同じ
    • 継承と同じくテンプレートメソッドパターンを使って include する側のオブジェクトが自然と特化するよう仕向ける
    • フックメソッドを使って include する側に super の送信を強制することを避ける

レガシーソフトウェア改善ガイドを読んだ

いくつかの書評を読んで、自身が所属するチームの活動に役立てられそうに思ったので読んでみた。

タイトルからレガシーコード改善ガイドを連想してしまうけれど、彼の本はコードの改善方法に主眼を置く一方、こちらでは、リファクタリングの手法やテストのアンチパターンVagrant と Ansible による開発環境構築の自動化などのコードやプロジェクトの具体的な改善方法に加え、レガシーコードはどのようにして生まれるか、改善する際にはどのような姿勢を取るべきか、どのような選択肢が存在するか、それぞれの選択肢はビジネス的な観点からどのように評価できるか、といったレガシーコードを取り巻く営みについても焦点を当てている。

さて、読んでみたところ、自身が新たな発見を得て「なるほど!!」となる内容は正直に言って多くなかった。しかしながら、これから初めてレガシーなプロダクトのプロジェクトに参画する人にはぜひオススメしたい1冊に感じた。この本を通じて、レガシーなプロダクトへの怒りに囚われず、冷静に原因を分析して着実な改善を進めるための見方を得ることができると思ったからだ。

個人的に参考になったのはビッグリライトの章だった。その章では著者の実体験を以って「そのプロジェクトは際限なく引き伸ばされるだろう」「あなたの新しい実装によって、独自の新しいバグが導入されることは、ほとんど確実である」「もし可能なら、私は段階的なリリースのアプローチを、強く推奨する」「既存のコードは「究極の真実のソース」ではなくリファレンスとして扱い、あなたが下す判断のガイドとして、あるいは論争に決着を付けるために、利用すべきだ」といったことが綴られている。最近会社でスタッフが使うあるアプリケーションを0から書き直したい想いがあって、来る日に向けて手始めに不要な機能を削っていたのだけど、この章のおかげで一度立ち止まって冷静に状況を見ることができたし、仮に今後ビッグリライトに踏み切るとしても、以前よりは良い進め方ができるだろうと思う。

レガシーソフトウェア改善ガイド (Object Oriented Selection)

レガシーソフトウェア改善ガイド (Object Oriented Selection)

結婚誕生

f:id:ravelll:20170312141339j:plain

結婚

3月10日に婚姻届を提出し、無事に受理された。

彼女とはしばらく前から同棲していたので大方の予想通り結婚が生活を突然変えるということは無かった。強いて言うなら、「妻」という呼称が堂々と使えるようになったというくらい。「彼女」という呼称への小っ恥ずかしさがいつまで経っても拭えずにいたのでやや寂しいながらありがたい。ちなみに家ではしばしば互いを夫ボーイ・妻ボーイと呼んでいる。

誕生日

3月14日で28歳になった。まじかよ!

就職してから年々順調に社会性を獲得してこのままでは没個性待ったなし、これじゃいかんのでは、という気持ちがあったのだけれど最近は幸せになれるならなんでも良いのではと考えている。

これは決してエンジニアとして突出した能力を持つことに前向きでなくなったという意味ではなくて、それについてはむしろ今まで以上に力を付けてますます楽しくやっていきたい気持ち。

ちなみに妻の誕生日も3月。3月のめでたさたるや並ではない。

干し芋リスト

贈り物は随時歓迎しております。

ウィッシュリストはこちらです。