2016-09 / 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30

2016-09-22 (木)

『オブジェクト指向設計実践ガイド』を読んだ [OOP][Ruby][Book]

本当に良い本でした。読んで良かった。初心者を中心に中級者にも刺さる
本だと思います。輪読などして、チームで読むとオブジェクト指向設計の
そもそもの話をしなくて良さそうです。



難しい話が易しく説明されており「あ、そうだったのか」と思うことが度々
でした。ボリュームも全9章とコンパクトで、1日1章読むのに丁度よかっ
たです。

読んでメモった箇所を中心にまとめていきます。


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


インスタンス変数へのアクセス方法を誤解していました。

P46
変数はそれらを定義しているクラスからでさえも隠蔽しましょう


今まで他のクラスから隠蔽する時は、直接 @hoge などにアクセスしてい
ましたが、中からも attr_reader などで隠蔽する必要があるそうです。
「データではなく、振る舞いに依存する」ためだそうです。

メモ化などでこうした手法は使っていたけど、単純な参照も隠蔽する必要
があるのですね...。

ただ、中からしか使わない変数も単純な attr_reader を使っていたのは、
納得いかなかったです。こうして外から隠蔽する必要はないでしょうか?

class Hoge
  attr_reader :hoge # 外からも参照される

  #...

  private
  attr_reader :hogehoge # 中からしか参照されない

  #...
end



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


「依存オブジェクトの注入(DI)」を中心に疎結合なコードの書き方がま
とまった章です。

DI は正直今までピンと来ていませんでしたが、この章を読んで完璧に理
解しました。10 年前から使っていました...。



数日経ってもまだ何か言ってる。




P80
自身より変更されないものに依存しなさい


この章はこれに尽きると思います。

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


P104
 仮にオブジェクトが人間だとして、自身の関係を説明できるとしましょ
う。すると、図4.5では、Trip は Mechanic に「私は自分が何を望んでい
るかを知っているし、あなたがそれをどのようにやるかも知っているよ」
と伝えているはずです。(中略)
 この手放しの信頼が、オブジェクト指向設計の要です。これによって、
オブジェクトは自身をコンテキストに縛り付けることなく、共同作業でき
るようになります。また、これは成長し、変化することが期待されるアプ
リケーションには必要不可欠です。
(太字は引用者によるもの)


これを読んで、なぜかアジャイルについて腑に落ちました。理解するのに
何年かかっているんだよ...。

※ アジャイルはオブジェクト指向を人に置き換えたもの

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


業務でサブクラスが super にメッセージを送るコードを頻繁に見かけま
す。P172 にこのリファクタリング方法が書かれていました。

やり方は簡単で、post_initialize のようなフックメッセージを用意する
だけ。そうすることで、サブクラスは必ず super を呼ぶ責任から逃れら
れます。「いつ」初期化が行われるか知らなくてよいのは大きい。結合度
の低減です。

最近は継承をなるべく使わず、委譲を使うことを意識していますが、継承
もちょっとしたテクニックで結合度を減らせることを学びました。

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


P202 に「リスコフの置換原則(LSP)」が書かれていました。

システムが正常であるためには、派生型は、上位型と置換可能でなけれ
ばならない


正直知らなかったのですが、これに限らずこの本には法則がいくつか出て
くるので、そもそもの知識として身に付けたいと思います。

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


P231
したがって、継承では、「自分が間違っているとき、何が起こるだろう」
という問いかけが特別に重要な意味を帯びてきます。


さきほどの super の話もそうですが、継承はただでさえ強い結合なので、
修正の影響を少しでも減らさなくてはいけません。

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


テストには多少自信があったのですが、この章を最初読んだ時、少々落ち
込みました。

P260 のようにスタブ前提のテストが奨励されており、今までの私の書き
方とはある意味真逆だったからです。

P261
アプリケーションがはっきりと間違っているにもかかわらず、テストはの
んきに、すべてうまくいっていると報告します。このような世界をつくっ
てしまう可能性があるゆえに、スタブ(とモック)はテストを脆くすると
警告する人がいるのです。


わたしです。^o^

でも読んでいて、DI などで疎に設計されたアプリケーション前提なのか
も?と思い直しました。密結合で使うのはなかなか危険かも。

とは言え、今後は少し考えを切り替えようと思いました。

以下は雑多な疑問や感想。

P272 では危険を承知でテストを書く前にリファクタリングをしているけ
ど、やらないほうが良いと思いました。

P279 はスタブ前提でも壊れづらいテストの書き方です。テストの
respond_to ってこういう時に使うのね。private メソッドを呼んでいる
かのテストは見たことがある...。

P290 では抽象スーパークラスもテストをしていました。私は今まで書か
ないようにしていましたが、前述の「リスコフの置換原則」に沿った設計
をしていれば、テスト可能という話です。

この章のテストは MiniTest で書かれているので、RSpec で書いてみよう
としましたが、GitHub にいくつかあったのでそれを読んで満足しました。

2016-09 / 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30

最終更新時間: 2019-11-18 01:04 JST

検索


最近の話題
- 2019-11-17
  3ヶ月間、総務省の家計調査に協力していた
- 2019-10-28
  『Clean Architecture』を読んだ
- 2019-10-10
  terraform-provider-healthchecksio を Terraform Plugin SDK に移行した
- 2019-09-20
  本番環境で heroku run する時の tips
- 2019-08-16
  『改訂2版 みんなのGo言語』を読んだ
- 2019-08-13
  『カード決済業務のすべて』を読んだ
  『実行力 結果を出す「仕組み」の作りかた』を読んだ
- 2019-08-05
  Heroku Logging Add-on Papertrail と LogDNA の比較
最近追記された記事
- 2019-02-11-1 (56日前)
- 2019-02-03-1 (56日前)
- 2019-01-28-1 (56日前)
- 2019-02-03-1 (98日前)
- 2018-11-28-1 (112日前)
- 2019-05-07-1 (192日前)
- 2018-04-30-1 (207日前)
- 2018-01-28-1 (219日前)
- 2019-02-11-1 (279日前)
- 2019-01-20-1 (297日前)
カテゴリ
- Anthy (3)
- Apache (11)
- Apple (1)
- ATOK (4)
- au (3)
- AWS (23)
- Bazaar (1)
- Berkshelf (2)
- BigQuery (1)
- BitBar (4)
- Book (107)
- Boxen (2)
- Bugsnag (1)
- capistrano (4)
- chalow (57)
- ChatWork (1)
- Chef (17)
- Chrome (3)
- Chromecast (1)
- CircleCI (10)
- clang (26)
- Comics (2)
- Cooking (10)
- cvs (15)
- cygwin (12)
- D3.js (1)
- Debian (55)
- Docker (4)
- E-mail (9)
- elasticsearch (4)
- Emacs (223)
- Emacs講座 (10)
- English (4)
- feedforce (7)
- fetchmail (3)
- Firefox (20)
- Fluentd (4)
- ftp (2)
- Game (21)
- GCP (1)
- Gem (5)
- Git (9)
- GitHub (23)
- golang (11)
- Google (1)
- gpg (4)
- GrowthForecast (7)
- Health (6)
- Heroku (20)
- Homebrew (10)
- HTML (6)
- iBook (1)
- iPad (1)
- iPhone (17)
- IRC (1)
- Jenkins (8)
- JS (1)
- Karabiner (1)
- KeySnail (3)
- Kibana (1)
- Kindle (1)
- Kubernetes (2)
- Langrich (7)
- LDAP (6)
- Life (24)
- Linux (7)
- Mackerel (1)
- macOS (1)
- Mew (18)
- MongoDB (1)
- Mozilla (19)
- Music (1)
- MySQL (1)
- NAS (4)
- nginx (6)
- NHK (1)
- Node (1)
- ntp (4)
- OOP (2)
- OpenID (2)
- openssl (1)
- Opera (2)
- OSX (41)
- Perl (14)
- PHP (19)
- PostgreSQL (1)
- procmail (4)
- Programing (3)
- Puppet (1)
- Python (2)
- Rails (13)
- Rake (2)
- RaspberryPi (2)
- Redash (1)
- RedHat (29)
- Redmine (3)
- RSpec (2)
- Ruby (52)
- samba (3)
- screen (7)
- sed (5)
- serverspec (6)
- sh (8)
- Slack (2)
- Solaris9 (22)
- Spring (2)
- ssh (4)
- StatusNet (21)
- svn (12)
- Swift (1)
- Tablet (1)
- tdiary (3)
- Terraform (2)
- Twitter (15)
- Twmode (6)
- Ubuntu (5)
- UNIX (102)
- vagrant (8)
- Video (21)
- vim (1)
- Wercker (9)
- Windows (29)
- Wine (3)
- XML (11)
- XP (1)
- zsh (26)
- インストールメモ (33)
- クイックシェイプ (12)
- ネタ (15)
- 勉強会 (17)
- 携帯 (6)
- 正規表現 (4)
過去ログ
2019 : 01 02 03 04 05 06 07 08 09 10 11 12
2018 : 01 02 03 04 05 06 07 08 09 10 11 12
2017 : 01 02 03 04 05 06 07 08 09 10 11 12
2016 : 01 02 03 04 05 06 07 08 09 10 11 12
2015 : 01 02 03 04 05 06 07 08 09 10 11 12
2014 : 01 02 03 04 05 06 07 08 09 10 11 12
2013 : 01 02 03 04 05 06 07 08 09 10 11 12
2012 : 01 02 03 04 05 06 07 08 09 10 11 12
2011 : 01 02 03 04 05 06 07 08 09 10 11 12
2010 : 01 02 03 04 05 06 07 08 09 10 11 12
2009 : 01 02 03 04 05 06 07 08 09 10 11 12
2008 : 01 02 03 04 05 06 07 08 09 10 11 12
2007 : 01 02 03 04 05 06 07 08 09 10 11 12
2006 : 01 02 03 04 05 06 07 08 09 10 11 12
2005 : 01 02 03 04 05 06 07 08 09 10 11 12
2004 : 01 02 03 04 05 06 07 08 09 10 11 12
2003 : 01 02 03 04 05 06 07 08 09 10 11 12
2002 : 01 02 03 04 05 06 07 08 09 10 11 12
2001 : 01 02 03 04 05 06 07 08 09 10 11 12