2009-06-23 23 views
21

私は数年前に仕事場でソフトウェアプロジェクトを余儀なくされ、すぐにC#を学ばなくてはなりませんでした。私のプログラミングの背景は弱いです(Classic ASP)。C#でインターフェイスを使用する利点は何ですか?

私は長年にわたりかなりのことを学んできましたが、C#をどのように学んだかという強制的な性質のため、私には明確な多くの基本的な概念があります。

特に、インターフェイスです。私は基本を理解していますが、アプリを書くときには実用的な使い方を考え出すのが苦労しています。なぜアプリケーション用のインタフェースを記述したいのですか?

おかげ ケビン

+7

ここをクリックhttp://stackoverflow.com/questions/56867/interface-vs-base-classここにhttp://stackoverflow.com/questions/444245/how-will-i-know-when-to- create-an-interfaceとmore for "c#interface"を検索します。 – Marc

答えて

16

インタフェースは何かがどのように動作するかを述べています。それを契約書やテンプレートと考えてください。これはInverson of ControlやDependancy Injectionのようなものにとって重要です。

私はIoCコンテナとして構造マップを使用します。これにより、すべてのクラスのインターフェースを定義することができます。あなたは

Widget w = new Widget(); 

を言うかもしれないどこで

IWidget w = ObjectFactory.GetInstance<IWidget>(); 

これは私のコードは、必ずしもウィジェットは本当に何であるかを言っていないという点で非常に強力であると言うでしょう。これは、ウィジェットがIWidgetのインターフェースに基づいて行うことができることを知っているだけです。

これはIoCコンテナを使用しているので、これでいくつかの素晴らしい機能が実現できるようになりました。ウィジェットを使用する必要がある私の単体テストでは、ウィジェット用のモックを作成できます。つまり、私のウィジェットは、データベースやWebサービスに接続することで非常に強力なことをします。私のモックは、これらのリソースへの接続をシミュレートし、スタブされたデータを返します。これにより、私のテストはより速く実行され、より信頼できる方法で動作します。私はStructureMapを使用しているので、私のコードの実際の使用中に私のウィジェットの実際の実装をロードし、プログラム中または設定によってテスト中にWidgetの模擬バージョンをロードするようにStructureMapに指示することができます。

また、私はIoCコンテナを使用しているので、データをキャッシュする3つの異なる方法を書き込むなど、アプリケーションにクールな新機能を提供できます。 Lucene.NETなどのツールを使用して、ローカルキャッシュ用にローカルの開発者ボックスキャッシュを使用できます。開発サーバーに.NETキャッシュを使用させることができます。このキャッシュは、1つのボックスで大きく動作します。そして、私の生産サーバがMemCache Win32やVelocityのようなキャッシュ層を使うという3番目の選択肢があります。 3つのキャッシング実装がすべて同じインターフェイスに準拠している限り、実際の実装は私(または自分のコード)にはまったく関係しません。私は単にStructureMapに現在の環境の実装を取得してから作業するように頼んでいます。

Dependency Injectionに従っているなら、インターフェイスはクラスクラスのコンストラクタのインターフェイスとしてクラスの使用法を宣言できるという点で、StructureMapなどのIoCコンテナでも便利です。その後、

public class Widget(IWidgetRepository repository, IWidgetService service) : IWidget 
{ 
    //do something here using my repository and service 
} 

そして私は、そのような私はコンストラクタでリポジトリまたはサービスを指定していないです。この

IWidget widget = ObjectFactory.GetInstance<IWidget>(); 

お知らせなどのStructureMapの方法によってウィジェットのインスタンスを新しいです。 StructureMapは、コンストラクタで指定されたインタフェースを使用して、適切なインスタンスを取得して渡す方法を知っています。これは非常に強力でクリーンなコードです!

すべてのインターフェイスの簡単な定義とそれらのいくつかの賢い使い方から!

0

良い記事です。

インターフェイスは、クラスまたは構造体がどのように動作するかをクライアントに保証するコントラクトです。

http://www.codeguru.com/csharp/csharp/cs_syntax/interfaces/article.php/c7563

これは、私が遭遇していることを説明するの明確な最も簡単な方法かもしれない:答えは、彼らはあなたドンオブジェクトを受け入れる建物ルーチンのかなりタイプセーフな手段を提供することである

」あなたのルーチンに渡されるオブジェクトについて知っている唯一のことは、彼らがあなたのルーチンのために存在しなければならない特定のメンバーを持っていることですそのオブジェクト。 私は、インターフェイスの必要性を与えることができる最良の例は、チーム環境です。お互いに話す。インターフェイスを使用することで、開発者がタイプに追加するメンバーを誤って解釈したり、インターフェイスを定義する別のタイプをどのように呼び出すかを開発者が誤って解釈する可能性がなくなります。インタフェースがなければ、エラーはシステムに入り込んでしまい、実行時まで見つけられない場合があります。インターフェイスと、タイプを定義する際にエラーがコストがはるかに小さいコンパイル時、ですぐにキャッチされている。IWriter 『ケース」

7

基本的なケースがある』。

はあなたが書くことができるクラスを作っていると仮定します()とpeek()のような便利な機能があります。

次に、新しいクラスを再作成するのではなく、プリンタに書き込むことができるクラスを作成したいと思います。 IWriterインターフェイス。

インターフェイスについてのすばらしいことは、あなたが何を知らずに、すべての書き込みコードを書くことができることですあなたの書き込み目標を事前に決めておいて、実行時に天候を決定してコンソールやプリンタに書きたい場合は、オブジェクトをコンソール/プリンタライタとして定義するだけで、何も変更する必要はありません彼らは両方とも同じフロントエンド(インターフェイス)を使用しているため、あなたの書くコードです。

0

bookは、すべてインターフェイスについて語ります。それは、インタフェースがクライアント、つまり呼び出し元に属しているという概念を促進します。それはいい考えです。 count()やget()を実装するために必要なものだけが必要な場合は、そのようなインタフェースを定義して、クラスにそれらの関数を実装させることができます。いくつかのクラスには他の多くの機能がありますが、あなたはそれらの2つだけに興味があります - あなたが作業しているクラスについて知る必要はありません。彼らが契約を満たす限り、それらを使うことができます。

1

例。レポートを表示するMDIアプリケーションを考えてみましょう。基本的に2つの異なるレポートタイプがあります。グラフ、グリッド。私はこれらのレポートをPDFで保存する必要があり、誰かに郵送する必要があります。ユーザーがPDFにレポートを保存するためにクリックメニューの イベントハンドラは、これを行うことができます:

void ExportPDF_Clicked(...) { 
    if(currentDocument is ChartReport) { 
     ChartReport r = currentDocument as ChartReport; 
     r.SavePDF(); 
    } else if(currentDocument is GridReport) { 
    GridReport r = currentDocument as GridReport; 
     r.SavePDF(); 
    } 
} 

を私はむしろ私のChartReportとGridReportは、このインターフェイスを実装するでしょう:

public interface Report { 
    void MailTo(); 
    void SavePDF(); 
} 

今私はでき操作を行います。

異なるレポートタイプで同じ操作を行う必要があり、他のコード(ファイルに保存し、ズームイン、印刷、など。)についても同様
void ExportPDF_Clicked(...) { 
    Report r = currentDocument as Report; 
    r.SavePDF(); 
} 

。 次の週にPpotTableReportを追加してRpoertを追加すると、上記のコードは正常に動作します。

1

IOCとDependency Injectionについては既に説明しましたが、私はあなたにそれらを見てほしいと思います。

しかし、インターフェイスでは、継承モデルを必要としないオブジェクトに対して契約を指定することが可能です。

私はクラスFooを持っていますが、関数xとyとプロパティzを持ち、私はその周りに自分のコードを構築しています。

Fooや他の種類のFooを実装する必要がある場合は、基本FooクラスをFooA、FooB、MyFooなどに拡張できますが、すべてのFoosにはFooの作成者がFooの基本クラスにアクセスし、内部の仕組みを理解していることを確認してください。 C#では、将来のFoosはFoo以外のものから継承することができないことを意味します。C#は複数の継承をサポートしていないからです。

また、Fooの今後の可能性のある状態を認識し、Fooクラスでそれらを禁止しないようにする必要があります。

IFooを使用すると、Fooフレームワークでクラスが動作するために必要な「契約」が記述されているだけで、fooクラスが継承しているか、 x fn yとz。これにより、フレームワークがより柔軟になり、将来の追加が可能になります。

ただし、Fooは、契約シナリオには適用されない大量のコアがベースに必要です。これは、継承を優先する場合です。

6

一つの単純な答え:使用インタフェースは契約ではなく実装に対してプログラムします。

これはおそらくどのように役立ちますか?インターフェイスの使用を開始すると、(うまくいけば)もっとゆるやかにクラスを結合する習慣が得られます。あなた自身の具体的なクラスに対してコードを書くときは、厳密な心配なしにデータ構造を突き刺すのは簡単です。あなたは、他のクラスや物事についてのすべてを「知っている」クラスで終わります。自分自身をインターフェースに限定することによって、インターフェースの契約を確実に果たすだけです。これは、しっかりとした結合に対して時には役立つ摩擦を加える。

0

インターフェイスから継承すると、インターフェイスに定義されているすべてのメソッドを実装する必要があります。別の方法として、これは通常のクラスではサポートされていない複数の継承をもたらす良い方法です。 http://msdn.microsoft.com/en-us/library/ms173156.aspx

0
第一原理に基づく

単純な答え:

プログラムは、約/信じる/理由を知ることができますどのような独自の形而上学(コードの現実/物質/原料)と認識論(と宇宙でありますコード)。良いプログラミング言語は、(あなたがあなたの宇宙が内部的に一貫していることを確認する)認識の厳密さを保証しながら、形而上学的な柔軟性を最大限にしようとします。

したがって、実装継承は、(あなたのコードについて何かを信じることを可能にする)認識上の制約として、形而上構造ブロック(あなたの小さな宇宙のコードを構成するもの)とインターフェース継承を考えてください。

あなたは何かを信じることができるようにするために、インターフェイスを使用します。ほとんどの時間はあなたが必要なすべてです。

0

あなたはインターフェイスの実用的な使い方を見つけるのが難しいと述べました。私は、サードパーティのプラグインが特定のルールに準拠しなければならないプラグインベースのアプリケーションなど、拡張可能なアプリケーションをビルドするときに、これらのルールはインタフェースによって定義することができます。

プラグインがロードされると、IServicesインターフェイスを実装するクラスをとるInitメソッドが必要になることがあります。あなたはIServicesインタフェースを実装し、次にあなたが一度それをインスタンス化するクラスを持っている場合

public interface IServices 
{ 
    DataManager Data { get; set; } 
    LogManager Log { get; set; } 
    SomeOtherManager SomeOther { get; set; } 
} 

public class MrPlugin 
{ 
    public void Init(IServices services) 
    { 
     // Do stuff with services 
    } 
} 

..だから、あなたは初期化時にすべてのプラグインに渡すことができ、彼らはあなたがインターフェイスで定義されているものは何でもサービスを使用することができます。

関連する問題