23

インターフェイスまたは抽象クラスを使用して、定義と実装を分離するためのより良いアプローチは何ですか?

私は実際には、参照カウントされたオブジェクトを他のオブジェクトと混在させるのは好きではありません。大規模なプロジェクトを維持する場合、これは悪夢になる可能性があると思います。

しかし、2 つ以上のクラス/インターフェイスからクラスを派生させる必要がある場合があります。

あなたの経験は何ですか?

4

6 に答える 6

8

これが「より良いアプローチ」の問題であるとは思えません。ユースケースが異なるだけです。

  • クラス階層がなく、クラス階層を構築したくない場合、および無関係のクラスを同じ階層に強制することさえ意味がない場合-しかし、知らなくても、とにかくいくつかのクラスを同等に扱いたい場合クラスの特定の名前->

    インターフェースは進むべき道です(たとえば、Javaの比較可能または反復可能について考えてみてください。これらのクラスから派生する必要がある場合(クラス=である場合)、それらはまったく役に立たないでしょう。

  • 妥当なクラス階層がある場合は、抽象クラスを使用して、この階層のすべてのクラスに統一されたアクセスポイントを提供でき、デフォルトの動作などを実装できるという利点もあります。

于 2010-02-17T08:36:03.920 に答える
3

Delphi では、定義を実装から分離する方法が 3 つあります。

  1. インターフェイス セクションに publuc クラスを配置し、実装セクションにその実装を配置できる各ユニットに分離があります。コードは同じユニット内に存在しますが、少なくともコードの「ユーザー」はインターフェースを読むだけでよく、実装の中身を読む必要はありません。

  2. クラスで仮想または動的に宣言された関数を使用する場合、サブクラスでそれらをオーバーライドできます。これは、ほとんどのクラス ライブラリが使用する方法です。TStream を見てください。これは、THandleStream、TFileStream などの派生クラスです。

  3. クラスの派生だけではなく、異なる階層が必要な場合は、インターフェイスを使用できます。インターフェイスは常に、COM ベースの IUnknown にモデル化された IInterface から派生します。参照カウントとクエリ タイプ情報が一緒にプッシュされます。

3 の場合: - TInterfacedObject から派生する場合、参照カウントは実際にオブジェクトの有効期間を処理しますが、これは確実ではありません。- たとえば、TComponent も IInterface を実装しますが、参照カウントは行いません。これには大きな警告が伴います。オブジェクトを破棄する前に、インターフェース参照が nil に設定されていることを確認してください。コミラーは、まだ有効に見えるがそうではないインターフェイスに deref 呼び出しを挿入します。第二に、人々はこの振る舞いを期待しないでしょう。

2 と 3 のどちらを選択するかは、非常に主観的な場合があります。私は以下を使用する傾向があります:

  • 可能であれば、仮想および動的を使用し、派生クラスでそれらをオーバーライドします。
  • インターフェースを操作する場合: interfcae インスタンスへの参照を変数として受け入れる基本クラスを作成し、インターフェースをできるだけ単純に保ちます。すべての側面について、個別の intercae 変数を作成してみてください。インターフェイスが指定されていない場合は、デフォルトの実装を配置するようにしてください。
  • 上記の制限が厳しすぎる場合: TInterfacedObject-s の使用を開始し、起こりうるサイクルとそれによるメモリ リークに注意してください。
于 2010-02-17T08:14:11.547 に答える
2

非常に大規模なプロジェクトでの私の経験では、両方のモデルがうまく機能するだけでなく、問題なく共存することさえできます。インターフェイスには、共通の祖先から派生していない複数のクラスに特定のインターフェイスを追加できるという点で、クラスの継承よりも利点があります。または、少なくとも、コードに新しいバグを導入するリスクがある階層にコードを導入する必要はありません。動作することがすでに証明されています。

于 2010-02-17T17:17:46.167 に答える
1

私は COM インターフェイスが嫌いで、他の誰かが作成した場合を除いて、決して使用したことがありません。これは、COM とタイプ ライブラリに関する私の不信感から来ているのかもしれません。インターフェイスを使用するのではなく、コールバック プラグインを使用してインターフェイスをクラスとして「偽装」したことさえあります。他の誰かが私の苦痛を感じ、インターフェイスの使用を疫病のように避けたのではないでしょうか?

私がインターフェースを避けることを弱点と考える人がいることは知っています。しかし、インターフェイスを使用するすべての Delphi コードには、一種の「コードの匂い」があると思います。

私は、コードをセクションに分割するためにデリゲートやその他の可能なメカニズムを使用するのが好きで、クラスでできることはすべてやろうとしますが、決してインターフェイスを使用することはありません。私はそれが良いと言っているのではなく、私には理由があり、ルールがあると言っているだけです (それは時々間違っているかもしれませんし、一部の人にとっては常に間違っているかもしれません): 私はインターフェイスを避けます。

于 2010-02-17T18:51:03.067 に答える