3

次の(非常に単純化された)構造のプロジェクトに取り組んでいます。

BaseClass

SubClassA : BaseClass
SubClassB : BaseClass

を使用するUI(多くのロジックを含む)がありSubClassA、それを別のコンポーネントに保存します。このコンポーネントBaseClassはパラメータとして受け取りますが、すぐに引数を にキャストしますSubClassB。UI が を渡しているため、これは失敗しますSubClassA

UI:

MyComponent.Save(subClassA)

Component:
Save(BaseClass baseClass)
{
SubClassB subClassB = (SubClassB)baseClass;

...

現在の実装では、UI で SubClassB のインスタンスを作成し、それを渡しますが、次のような多くのコードが発生します。

SubClassB.Property1 = SubClassA.Property1a

2 つのサブクラスが実装する共通のインターフェイスを作成することを考えています。大変な作業になりますが、ゆっくりと、現在の非常に深いヒエラルキーをフラット化できると思います。他のサブタイプを使用するために UI またはコンポーネントのいずれかを作り直すことは、構造が異なるのと同じくらいの作業になります (ただし、多くのフィールドがマップされます)。インターフェイスアプローチは正しい方法ですか? 私に欠けているものがあるかもしれないと感じています。

4

3 に答える 3

2

SubclassASubclassBが の能力によってのみ関連している場合Save、はい、BaseClass両方のサブクラスが実装するインターフェイスとしてより適切です。

差し迫った問題をすぐに解決することはできません: 基本クラスから (間違った) 派生クラスへのコンポーネントのキャストです。ここで行うリファクタリングにはいくつかのレベルがあるようです。コンポーネントを a にキャストしてSubclassA使用するようにコードを修正するのはもったいないと思います。コンポーネントを変更して、単一の共通型で動作できるようにすると、大きなメリットが得られます。

深い階層をフラット化すると、他にも多くの利点が得られます。たとえば、単純化するなどです。それらがすべて実装するいくつかのインターフェースが最終的に存在する場合、それは必ずしも悪いことではありません。ただし、パックでハンティングする多くのインターフェイス タイプに注意してください。

要するに、UI とコンポーネントの両方、およびその他のコードも、実装クラスの知識がなくても、少数のインターフェイスだけで機能するように作り直すと、利益が得られます。

于 2013-07-18T15:09:40.590 に答える
2

消費者から観点から言えば、インターフェースは抽象クラスができるほとんどすべてのことを行うことができます (主な例外は、クラスがフィールドを byref として公開できることですが、インターフェースにはそうする手段がなく、クラスに関連付けられた静的メンバーをクラス名、インターフェイスに関連する静的メンバーは別の名前でグループ化する必要があります)。フィールドを byref として公開する必要があるまれなケースを除いて、抽象クラスの主な利点は実装側にあります。インターフェイスに関連付けられたすべての機能は、それを実装するクラスの 99% に共通の機能であっても、それを実装するすべてのクラスで個別に提供する必要があります。対照的に、抽象クラスから派生した具象クラスの 99% が特定のメソッドを同じ方法で実装する場合、抽象クラスがそのメソッドを一度定義すれば、派生クラスは何の注意も払わずにそれを継承することができます。このような利点は素晴らしいことですが、大きな落とし穴があります。つまり、クラスは他の 1 つのクラスからしか機能を継承できません。インターフェイスには機能が含まれていないため、任意の数の他のクラスから継承できます。

抽象クラスを定義する場合、多くの場合、(抽象クラスが実装する必要がある) 同じパブリック機能を含むインターフェイスも定義し、抽象クラス型の変数またはパラメーターを使用しないようにすることをお勧めします。これにより、抽象クラスから継承できる実装は、実装が容易になる利点を実現できますが、他の何かから継承する実装を定義することも可能になります。他の型から継承する実装を書くのは手間がかかりますが、コードが変数、フィールド、またはパラメーターの宣言で抽象クラス型を使用しない場合、抽象クラスの派生物を使用するコードは、次のインターフェイス実装でも同様に機能します。しないでください。

于 2013-07-18T15:32:07.453 に答える