ブログ 約3分

OOP vs ジェネリクス:「Is a」と「Has a」のアプローチ

Share this article
OOP vs ジェネリクス:「Is a」と「Has a」のアプローチ

Bjarne Stroustrupが指摘しているように、「C++はマルチパラダイム言語」です。C++はさまざまなプログラミングスタイル、つまりパラダイムをサポートしており、オブジェクト指向プログラミングはその1つにすぎません。他には、構造化プログラミングやジェネリックプログラミングなどがあります。

Thomas Beckerがこの興味深い記事で説明しているように、ジェネリックプログラミングとOOPの間には緊張関係があります。その記事で引用されている、C++の重鎮であるAlexander StepanovのOOPに関する意見は次のとおりです。

Let us start with a little trivia quiz. Who said the following things about object-oriented programming?

"I find OOP technically unsound."

"I find OOP philosophically unsound."

"I find OOP methodologically wrong."

"I have yet to see an interesting piece of code that comes from these OO people."

"I think that object orientedness is almost as much of a hoax as artificial intelligence."

All the quotes above are from an interview with Alexander Stepanov, the inventor of the STL and elder statesman of generic programming.

To have a concrete idea about the generics flexibility, let’s compare the implementation of a class calculating a tax in OOP and generic programming.

ここでは、2つのアプローチの大きな違いを見ていきます。この違いが、Alexander StepanovのOOPアプローチに対する意見を説明する手がかりになるかもしれません。例として、基本的な税額計算機を使って説明します。

generics1

CTaxCalculatorは、ICalculatorから派生したクラスとのみ連携します。アルゴリズムを実装するには、ICalculatorを継承し、いくつかの仮想メソッドをオーバーライドする必要があります。

対照的に、以下はジェネリックなTaxCalculatorの例です:

generics2

CGenericTaxCalculatorクラスは、特定の種類のクラスに限定されず、その型のクラス階層に関係なく、税額を計算できるあらゆる型と連携できます。

OOPアプローチは、どちらかと言えば「is指向のアプローチ」です。継承が過剰に使われており、ほぼすべてのOOPコードでは、クラスAは、Bが抽象クラスかどうかに関係なく、別のクラスの一種 である 場合に、別のクラスBと連携します。

一方、ジェネリックアプローチでは、クラスAは、Bが特定のメソッドとフィールドを スキルを持つ 場合にBと連携します。特定のクラスを継承する必要はありません。

このためジェネリックプログラミングはより自然で柔軟です。開発者は「has指向のアプローチ」を採用できます。一方OOPは、継承によって生じる強い結合のため柔軟性に欠け、開発者は「is指向のアプローチ」に従うことを強いられます。

考えてみてください。「has指向のアプローチ」の方が自然です。実際、現実世界では、私は特定の スキルを持つ 人と協力します。その人が特定の家系の出身 である かどうかは関係ありません。

Andrei Alexandrescuが指摘しているように、ジェネリックプログラミングの柔軟性は、現代的なC++設計において好まれる選択肢にし得るものです:

Modern C++ Design defines and systematically uses ジェネリックコンポーネント - highly flexible design artifacts that are mixable and matchable to obtain rich behaviors with a small, orthogonal body of code.

彼の発言では、次の3点が特に興味深いです:

  • Modern C++ Designでは、定義され、 体系的に使用される ジェネリックコンポーネント。
  • 高度に 柔軟な 設計。
  • Obtain rich behaviors with a 小さく直交した コード本体で、豊かな振る舞いを実現する。

要約すると、ジェネリックプログラミングはOOPアプローチよりも自然で柔軟であり、効率的なコードを書くための選択肢をより多く提供します。

Share this article