初心者データサイエンティストの備忘録

調べたことは全部ここに書いて自分の辞書を作る

オブジェクト指向設計実践ガイド【第5章】まとめ

オブジェクト指向の設計方法を学んでいます。 今回は、「オブジェクト指向設計実践ガイド」の「第5章:ダックタイピングでコストを削減する」を読みました。 なお、使用する言語はPythonです。

(過去記事)

aisinkakura-datascientist.hatenablog.com

aisinkakura-datascientist.hatenablog.com

aisinkakura-datascientist.hatenablog.com

aisinkakura-datascientist.hatenablog.com

ダックタイピングとは?

あるオブジェクトのメソッドを呼び出す際に、そのオブジェクトが何であるかを意識せずにメソッドを呼び出せるよう実装することをダックタイピングと言います。

ただ、これだけだと何を言っているのか全くわからないと思うので、早速例を挙げます。

上に挙げたスクリプトは、Exampleクラスのfuncメソッド内で、tripオブジェクトの種類に応じた場合分けを行っています。 具体的には、Exampleクラスのtripオブジェクトが、TripAのインスタンスであれば、TripAのメソッドfuncAを実行し、TripBのインスタンスであれば、TripBのメソッドfuncBを実行しています。

このようなコードにおいて、funcメソッド内で新たにTripC、TripDについて実装が必要になった場合、if文を増やして実装することが考えられます。しかし、このような実装方法はTripC、TripDの実装に加えて、Example内の改修も必要となります。したがって、単純にif文を増やすような実装をすると改修コストが高くなりかねません。そこで現れたのがダックタイピングです。

ダックタイピングを使って実装したコードを下記に挙げます。

Exampleクラス内のfuncメソッドの内部をif文を使わない形に実装しました。その代わり、TripAとTripB内のメソッドの名前を同じfuncに統一しています。TripC、TripDを実装する際も、TripC、TripDに実装するメソッドをfuncに統一することでExampleクラスに対する改修を全く行う必要がありません!
オブジェクトに依らず同じ形式でメソッドを呼び出せるようにしておくことがポイントです。

どのようにダックタイプを見つけるか?

一言でいえば、if文やmatch文で分岐されている箇所にダックタイプが隠れている可能性があります。上記の例においても、tripオブジェクトの種類に応じてif文で分岐していました。これを一つの種類にまとめようとしたときに、ダックタイプを導入します。

動的型付けと静的型付け

本章におまけ的に書かれていた議論です。まず、大前提としてダックタイプは動的型付け言語でしか使うことができません。なぜなら、呼び出し元が複数タイプのオブジェクトを同じように呼べるようにしておく必要があるからです。

下記のコードをご覧ください。

こちらのコードは、class Aに対するcountにおいてはlistに含まれるdogの数を数えています。一方で、class Bに対するcountにおいては、DataFrameに含まれるdogの数を数えています。このように、countの対象が異なっていてもCountは対応できます。これは、Pythonが動的型付けだからできることです。

以上のことから、本書では静的型付け言語を選択せざるを得ない場合を除いて、できるだけ動的型付け言語を使ってアプリケーションを作りましょうというようなことが書いてあります。

まとめ

本記事では、オブジェクト指向設計実践ガイドの第5章を通じてダックタイピングについて説明しました。 ダックタイピングとは、複数タイプのオブジェクトを統一的に実装するための手法であり、これにより場合分けのパターンが増えた場合における改修コスト抑制をすることができます。

また、ダックタイプを見つけるコツとしては、if分やmatch文で実装している箇所に注目することです。このような箇所は、ダックタイプを見つけることでif文やmatch文を消すことができる可能性があります。