2009-08-07 12 views
1

インタフェースと抽象基本クラスを含むオブジェクト指向設計を含む賢明な人々のために、いくつか質問があります。次のシナリオを検討してください:オブジェクト指向 - このインタフェース宣言を配置する場所

私は抽象バスクラス "DataObjectBase"と派生クラス "UserDataObject"を持っています。私はまた、 "IDataObject"というインターフェースを持っています。もちろん、インタフェースでは、データオブジェクトが公開しなければならないすべてのパブリックメソッドとプロパティが公開されているため、抽象ベースがすべてのデータオブジェクトに共通のメソッドとプロパティを実装していると推測できます。

私の質問は、抽象バスクラスのDataObjectBaseがインターフェイスIDataObjectで指定されたすべてのものを実装していれば、そのインターフェイスを基底クラスまたは派生クラスで宣言する必要がありますか?

基本クラスで宣言されたC#インターフェイスでは、派生クラスにimplicityが適用されますが、これがベストプラクティスですか?基本クラスにインターフェイスを実装すると、派生クラスがインターフェイスを実装することはあまり明白ではありませんが、インターフェイスを派生クラスごとに指定する必要があります。

さらに、基本クラスが抽象クラスでなかった場合、推薦は変更されますか?

2番目のサブ質問:基本クラスがIDataObjectインターフェイスのすべてのメソッド/プロパティを実装している場合は、インターフェイスも必要ですか?基本クラスのtypenameは、インタフェース名の代わりに単純に使用できます。つまり、

private DataObjectBase _dataObject;
プライベートIDataObject _dataObject;

上記の例(ここでもベースはインターフェイスによって公開されるすべてのものを実装します)では、両方に同じ派生型を割り当てることができます。個人的に私はいつもこのような状況でインターフェイスを使用していますが、私は人々の考えを聞くことで躊躇しています。

ありがとうございます。

答えて

1

このような問題について私が考えているのは、コードを読んでいる人々を考えてみることです。また、システム全体の保守性も考慮してください。

まず、インターフェイスを使用する予定のコードがあります。インターフェイスに関して書かれていますが、作成者は実装に関心がありません(必要があります)。だから私たちはInterfaceクラスを提供しています。その観点から、抽象基本クラスは多くの可能な実装階層の1つにすぎません。実装の詳細についてこの役割を伝えないでください。インターフェイスを維持します。

次に、私たちは実装を設計している役割を持っています。彼らは1つの可能なアプローチを思いついて、いくつかのバリエーションを発見するので、共通のコードをまとめたいと思っています。抽象基本クラス - 一般的なものをここに記入し、詳細な実装者がその隙間を埋めるようにします。抽象メソッドを提供することによってそれらを助ける "あなたのコードはここに行く"。これらのメソッドは、インタフェース内のメソッドである必要はないことに注意してください。また、この抽象基本クラスはさらに1つのインタフェースを実装するかもしれないことに注意してください! (CleverThingWorkerやIntermediateWorkPersisterなど)

次に、詳細な実装を実際に行う役割があります。ギャップをここに記入してください。死んで理解しやすい。この場合、Interfaceをそのように考える必要はありません。あなたの仕事は、その抽象クラスをコンクリートにすることです。

ボトムライン...私は両方のインターフェイスとベースクラスを使用します。基本クラスにインターフェイスを配置します。我々はそれを実装クラスに追加することによって付加価値を追加しません。

1

ユーザークラスがの場合、常には1つの基本クラスから継承されますが、インターフェイスは不要です。インタフェースに一致するが基本クラスから派生しないクラスを持つ可能性がある場合は、インタフェースを使用します。

インターフェイスが基本クラスに隠れているため、ユーザークラスですぐに表示されないインターフェイスは、通常のことであり、コンパイラによって処理できます。これは、DataObjectBaseと同様に、UserDataObjectにIDataObjectと一致する名前が付いています。 IDataObjectから継承しているというクラスファイルにコメントを追加できますが、IDataObjectから継承しているDataObjectBaseから継承していることがわかります。

0

言及する必要があるもう1つのことは、インターフェイスを使用することで自動化されたテストを簡単に実装できることです。

たとえば、「DatabaseConnectionLostException」などのインターフェイスのメソッドの1つが例外をスローし、クライアントコードがそのような状況で正しく動作するかどうかをテストするとします。

例外をスローするインタフェースの実装を提供して、テストを記述できるようにするのは簡単です。

インターフェイスの代わりに抽象基本クラスを使用した場合、この操作はかなり難しくなります(OK、Mockを使用できますが、インターフェイスソリューションはよりクリーンです)

関連する問題