オブジェクト指向シリーズ。ダックタイピング・・読む前は名前は聞いたことあるような気がする・・程度で細かいことは何一つわからない状態でした。今回具体的なコード例があった分イメージを何とかつかむことはできた(ような気がします。)
ダックタイピング
定義
そもそもの定義が難しい・・
Wikiには以下の通り。
ダック・タイピング(duck typing)とは、Smalltalk、Perl、Python、Rubyなどのいくつかの動的型付けオブジェクト指向プログラミング言語に特徴的な型付けの作法のことである。それらの言語ではオブジェクト(変数の値)に何ができるかはオブジェクトそのものが決定する。つまり、オブジェクトがあるインタフェースのすべてのメソッドを持っているならば、たとえそのクラスがそのインタフェースを宣言的に実装していなくとも、オブジェクトはそのインタフェースを実行時に実装しているとみなせる、ということである。
いやー何言っているかさっぱりわからん(汗)まあ辞書的に定義するとこんな例になりますよね・・・例によって検索するといい例があったのでリスペクトも込めてリンクします。
自分なりに解釈すると・・・
同一性のある処理(if,switchなどで分岐されるタイプ)の場合、インターフェイス(具体的にはメソッド名)を共通にして変更に強いコードを作る考えということでしょうか。
実際のコーディング上のコツ
- 安易にif,switchで複数で条件分岐を行わない(条件分岐された場合共通化を考える)
- 上位のプログラム(呼び出し側っていったらいいのかな)ではインとアウトのみ定義しておく(逆に言うと、ここが厳密でないとまずい)
- 内部の詳細な処理は内部のプログラムに任せる
感想
疎結合とかDIの有用性っていう概念が少しずつわかりかけてきました。2年ぐらい前に聞いたときはさっぱりイメージが出来なかったんだけれど・・・実際に自分で開発・保守をしてみると変更の時に耐え切れず残念なコードを書くことが非常に多かったです。
そんなときにああでもない、こうでもないとうんうんうなりながら、本書のような本を読むとその有用性がはっきりわかります。
変更により残念なコードになるのを防ぐためには変更がありそうな部分には「タッチしない(上記のリンクの例でいうと各動物のクラスだったり、料理だったりする)。」「上位側ではインとアウトのみ定義し、ふるまい自体は各クラスに任せる」という考え方が大事になってきます。
今までは上記のような場合、継承を使っていたんだけれども、継承がうまく使えない場合に知っておくとよさそう。
ここ数日、単一責任、依存関係の管理、インターフェイス、ダックタイピングとやってきましたが、オブジェクト指向の要点としては自分なりには下記の通り。
- コードを単一の機能(クラス)ごとに分ける
- 各機能(クラス)が何を行うか、別の機能(クラス)はタッチしない
- 機能ごとの依存度をとにかく減らす
- 詳細な機能はなるべく隠し、インとアウトだけをしっかりと定義しておく
今まではフィーリングに近い感じで画面ごとにクラスを作っていました・・・オブジェクト指向では「依存度を減らす」「内部の詳細構造を隠す」ということが大事で、詳細部分を公開しないことによって外部との依存度がへり、結果として変更に強いコードができます。
この意識が今まであまりなかったのですが、オープンソースなどみていますと、1行のメソッドをラッピングしていることにはこういう意図があったのかと思い、保守性を上げるための工夫というものがおぼろげながらわかりました。
このような工夫はテストをするときにも非常に有効です。
例えばプログラムでデータをもらう場所というのはデータベースだったり、外部ネットワーク(APIだったり、メール)しますが、これらとの連携を行う場合、コードが分割されていないとテストが結構大変です。