設計された継承

2006年10月6日

オブジェクト指向の世界で長年議論されていることの一つに、オープンな継承と設計された継承の間の議論があります。設計された継承の原則は、おそらくJosh Blochの言葉「継承のために設計し文書化するか、そうでなければ禁止する」に最もよく要約されます。このアプローチでは、どのメソッドを継承できるかを慎重に決定し、他のメソッドをシールしてオーバーライドされないようにします。

設計された継承に対する最も一般的な議論は、継承は非常に密接な(そしてカプセル化を破る)関係であるため、サブクラスがメソッド呼び出し時に必要な動作を省略するなどして、事実上スーパークラスを壊すのが簡単であるということです。

多くの開発者、特に実現を促す姿勢を持つ開発者は、このスタイルの議論は説得力がないと感じています。私がより魅力的に感じた別の議論は、XOMの設計原則について議論しているときのElliote Rusty Haroldの議論です。ここでのポイントは、「APIは専門家が非専門家のために書く」ということです。ライブラリの作成者は、ライブラリが動作するテクノロジーに精通している必要があります。彼女は、ライブラリユーザーのためにこのテクノロジーを簡素化するよう努める必要があります。カプセル化は秘密を隠すことであるため、優れたライブラリは、呼び出しや継承を通じてライブラリを使用するかどうかにかかわらず、あらゆる種類の複雑さと危険な点をライブラリユーザーから隠すべきです。したがって、XOMでは、ライブラリクラスを安全にオーバーライドして必要なことを実行できますが、ライブラリは、私が他の方法で起こりうるすべてのことについて心配する必要なく、適切に構成されたXMLを生成することを保証します。

このような議論は、ライブラリ作成者は賢く、ユーザーは愚かであるという含みを持つ通常の議論よりも、はるかに説得力があります。これは能力の問題ではなく、詳細な知識の問題です。私はXMLの汚い詳細についてできる限り無知でいたいのです。これらの種類の詳細を理解する必要性を軽減することで、私は実際に達成したいタスクに脳の力を使うことができます。

この説得力のある議論にもかかわらず、私の直感、そして私が実現を促す姿勢を持っているという事実から、オープンな継承を好む傾向があります。おそらく問題の核心は、継承の安全な領域を示すために使用するメカニズムでしょう。通常、私たちにはクラスとメソッドをシールする機能しかありません。両方の陣営をなだめるための代替案は、シールを克服する能力を持つことです。そうすれば、設計されていないものをオーバーライドするためにわざわざ行う必要があります。シールを明示的に開かない場合、コンパイラは通常の継承のみを許可しますが、シール開放メカニズムを使用すると、コンパイラは信頼をあなたに委ねます。そして、あなたは結果に責任を負います。したがって、私はJosh Blochの「禁止」を「推奨しない」に置き換えたいと思います。

より広い視点から見ると、呼び出しと継承の両方において、インターフェースについて考える方法はまだ改善の余地が多くあると推測しています。コンシューマードリブン契約のようなアイデアは、インターフェース定義を持つことの意味を再考するのに役立つ必要があります。答えが何であるかはわかりませんが、良い答えは私たち全員を驚かせるだろうと思います。