web-dev-qa-db-ja.com

オブジェクト指向言語での一般的な操作の設計

[〜#〜] sicp [〜#〜] で興味深い引用を見つけました。これは、オブジェクト指向設計に非常に関連していると思います。

一般に、1つのタイプに複数のサブタイプがあることがわかります。たとえば、三角形と四角形はどちらもポリゴンのサブタイプです。さらに、1つのタイプに複数のスーパータイプが含まれる場合があります。たとえば、直角二等辺三角形は、二等辺三角形または直角三角形のいずれかと見なすことができます。この複数のスーパータイプの問題は、階層内のタイプを「上げる」独自の方法がないことを意味するため、特に厄介です。オブジェクトに操作を適用するための「正しい」スーパータイプを見つけるには、apply-genericなどの手順の一部でタイプネットワーク全体をかなり検索する必要があります。通常、タイプには複数のサブタイプがあるため、タイプ階層の「下」に値を強制変換する場合にも同様の問題があります。大規模システムの設計でモジュール性を維持しながら、相互に関連する多数のタイプを処理することは非常に困難であり、現在多くの研究が行われている分野です。

多くのサブタイプを持つタイプは、主流の言語では非常に一般的だと思います。複数の継承またはインターフェースを使用して、複数のスーパータイプを持つタイプも可能です。

この引用を読んだとき、私はポリモーフィズムとキャスティングについて考えました。ですから、この問題はテキストが示唆するほど難しくはないと思います。ポリモーフィズムは本当にこの問題を解決しましたか?

大規模システムの設計でモジュール性を維持しながら、相互に関連する多数のタイプを処理することは非常に困難であり、現在多くの研究が行われている分野です。

それは今日でも本当ですか?または、この見積もりは古くなっていますか?それでも当てはまる場合、オブジェクト指向言語で関連する型を使用して何かをモデル化することが非常に難しい例をいくつか挙げていただけますか?

私は言語デザインに詳しくないので、引用の理解が正しいかどうか誰かに説明してもらいたいです。

2
morbidCode

あなたの引用は今日でも真実です:

大規模システムの設計でモジュール性を維持しながら、相互に関連する多数のタイプを処理することは非常に困難であり、現在多くの研究が行われている分野です。

非常に大規模なオブジェクト指向システムをプログラミングすると、相互に関連するクラスと依存関係がますます増え、主流の言語が進化しました。

たとえば、C++は、クラスと継承を使用して1983年にリリースされました。 1986年、B.Stroustrupは、オブジェクト指向とデータ抽象化全般について、いくつかの欠落している機能を特定しました。 1989年に彼は言語に 多重継承 を追加しました。 MIは(論争にもかかわらず)非常に強力な言語構造ですが、一般的な問題を解決するためにMIを使用すると、依存関係が派生ツリーに伝播します。そのため、1991年に テンプレート が導入され、真のジェネリックプログラミング(クラスと関数の両方)が可能になりました。これは素晴らしい前進でしたが、使用するのはやや複雑でした。テンプレートの使用を容易にする追加の型控除機能を取得するには、2011年を待たなければなりませんでした。

ジェネリックプログラミングとテンプレートは、型階層や継承とは大きく異なります。 SICPの章で説明されているように、オブジェクトを上位型に上げて、一般的な操作を定義できる祖先を見つけることはできません。テンプレートアプローチは、より term rewriting のようなアプローチであり、テンプレートのジェネリック型が式の具象型と一致し、コンパイル時に型を推測し、コードを書き換え/置換/生成することができます。この根本的に異なるアプローチが真のブレークスルーを可能にしたと私は信じています。

Javaはより最近のもので、1995年に作成されました。多重継承のない階層型システムですが、代わりに interfaces を使用します。これらはMIと同様の課題を解決することを可能にしますが、インターフェースの背後にある考え方は抽象型です。ただし、時間の経過とともに、インターフェイス(C++のMIと同様)は、特に一般的な問題を解決する場合に、必ずしも望ましいとは限らない入力制約を課すように見えました。そのため、2004年に generics がJavaに追加されました。

強い需要がなければ、主流の言語はこのように進化しないので、その必要性が示されます。

たとえば、仮想/ポリモーフィック関数を実装するためのいくつかの優れた手法は、「C++の設計と進化」、Bjarne Stroustrup、1994で詳細に説明されており、現在は広く知られています。簡単そうに見えるかもしれませんが、ここに到着するには多くの作業が必要でした。多重継承の場合、コンパイラでそれを実装する方法を説明するいくつかの 特許 があります(それらがまだ有効かどうかはわかりませんが)。したがって、言語の歴史の時間経過が示唆するように、今明らかであるように見えることは、それがゼロから発明されなければならなかった場合、必ずしも明白ではありません。

1
Christophe