第5章 ダックタイピングでコストを削減する
ダックタイピングとは、暗黙的なパブリックインターフェース。オブジェクトの振る舞いは、コードとして存在する明示的なインターフェースではなく、「どのメッセージに応答するか」という暗黙的なインターフェースに依存することになる。
オブジェクト指向設計実践ガイド ~Rubyでわかる 進化しつづける柔軟なアプリケーションの育て方
- 作者: Sandi Metz,?山泰基
- 出版社/メーカー: 技術評論社
- 発売日: 2016/09/02
- メディア: 大型本
- この商品を含むブログ (6件) を見る
ダックタイピングの理解
あるオブジェクトにメッセージを送ろうとするとき、そのオブジェクトの型を知っている必要はない。重要なのは、そのメッセージに応答可能かどうかだけである。オブジェクトが何で「ある」かではなく何を「する」かに注目する。
ダックタイピングによって、簡潔な記述ときれいな構造を両立することもできれば、理解不能な混沌を作り出すこともできる。コードとしてインターフェースを定義しなくて良いということは、好きにして良いということではない。クラスやインターフェース(Java)と同様に設計し、ドキュメントを整備する必要がある。
すべてがコード上に現れる具象的なコードは理解しやすいが拡張しにくい。(ダックタイピングのように)暗黙的な取り決めがある抽象的なコードは拡張性は高いがひとめで理解しにくい。このトレードオフが常に存在する。
Rubyのようにダックタイピングが使えない場合にポリモーフィズムを実現するには継承、Mix-inなどがある。
ダックタイピングの利用
ダックタイピングを使うべきはどんなときか、いくつかパターンが存在する。
ダックタイピングを使えないか検討すべき項目
- クラスで分岐するcase文
- kind_a?, is_a?
- responds_to?
これらが現れたとき、なにか「共通のもの」がそこには存在するはず。
def start(args) args.each do |a| case a when Bar a.run when Baz a.init when Qux a.ignite end end start([bar, baz, qux])
Bar, Baz, Quxはどれも何かを始めるためのメソッドを持っているが、それらすべてばらばらの名前になっているので、呼び出す側がそれぞれのクラスの実装を知っている必要があった。しかしBar, Baz, Quxがすべて start
というパブリックメソッドを実装している(暗黙的に"Startable"インターフェースを実装している)とすれば、こうできる。
def start(args) args.each(&:start) end start([bar, baz, qux])
オブジェクト指向設計実践ガイド ~Rubyでわかる 進化しつづける柔軟なアプリケーションの育て方
- 作者: Sandi Metz,?山泰基
- 出版社/メーカー: 技術評論社
- 発売日: 2016/09/02
- メディア: 大型本
- この商品を含むブログ (6件) を見る