[解決済み] 実装ではなくインターフェースにプログラムする」とはどういう意味ですか?
質問
デザインパターンについて読んでいると、このようなフレーズに出会います。
しかし、私には理解できないので、どなたか説明していただけませんか?
どのように解決するのですか?
<ブロッククオートインターフェースは、単なる契約や署名であって 実装について何も知らない。
インターフェースに対するコーディングとは、クライアントコードが常にファクトリーから供給されるインターフェースオブジェクトを保持することを意味します。ファクトリーから返されるインスタンスは、ファクトリーの候補クラスが必ず実装しているInterface型になります。この方法では、クライアントプログラムは実装について心配する必要はなく、インターフェイスシグネチャによって、どのような操作が可能かが決定されます。これは、実行時にプログラムの動作を変更するために使用することができます。また、メンテナンスの観点からも、はるかに優れたプログラムを書くことができるようになります。
ここでは、基本的な例をご紹介します。
public enum Language
{
English, German, Spanish
}
public class SpeakerFactory
{
public static ISpeaker CreateSpeaker(Language language)
{
switch (language)
{
case Language.English:
return new EnglishSpeaker();
case Language.German:
return new GermanSpeaker();
case Language.Spanish:
return new SpanishSpeaker();
default:
throw new ApplicationException("No speaker can speak such language");
}
}
}
[STAThread]
static void Main()
{
//This is your client code.
ISpeaker speaker = SpeakerFactory.CreateSpeaker(Language.English);
speaker.Speak();
Console.ReadLine();
}
public interface ISpeaker
{
void Speak();
}
public class EnglishSpeaker : ISpeaker
{
public EnglishSpeaker() { }
#region ISpeaker Members
public void Speak()
{
Console.WriteLine("I speak English.");
}
#endregion
}
public class GermanSpeaker : ISpeaker
{
public GermanSpeaker() { }
#region ISpeaker Members
public void Speak()
{
Console.WriteLine("I speak German.");
}
#endregion
}
public class SpanishSpeaker : ISpeaker
{
public SpanishSpeaker() { }
#region ISpeaker Members
public void Speak()
{
Console.WriteLine("I speak Spanish.");
}
#endregion
}
<イグ
これはあくまで基本的な例であり 実際に原理を説明するのは この回答の範囲を超えています。
EDIT
上の例を更新し、アブストラクトを追加しました。
Speaker
基底クラスです。今回の更新では、すべてのSpeakerに"SayHello"の機能を追加しました。すべてのスピーカーは "Hello World" を話します。ということで、似たような機能を持つ共通機能です。クラス図を参照して、以下のようになります。
Speaker
抽象クラス実装
ISpeaker
インターフェイスを実装し
Speak()
を実装するのは、各スピーカーの実装に責任があることを意味します。
Speak()
メソッドと異なるので
Speaker
から
Speaker
. しかし、すべてのスピーカーは全員一致で "Hello" と言います。そこで、抽象的な Speaker クラスに "Hello World" と言うメソッドを定義して、それぞれの
Speaker
の実装は
SayHello()
メソッドを使用します。
というケースを考えてみましょう。
SpanishSpeaker
はSay Helloできないので、その場合は
SayHello()
メソッドを作成し、適切な例外を発生させます。
なお インターフェイスに変更はありません。 ISpeakerです。また、クライアントコードと SpeakerFactory も影響を受けません。 は変更されません。そしてこれを実現するのが プログラミング・トゥ・インターフェイス .
そして、ベースとなる抽象クラス Speaker を追加し、それぞれの実装を少し修正するだけで、元のプログラムを変更することなくこの動作を実現することができるのです。これは、どのようなアプリケーションにも求められる機能であり、アプリケーションの保守性を向上させるものです。
public enum Language
{
English, German, Spanish
}
public class SpeakerFactory
{
public static ISpeaker CreateSpeaker(Language language)
{
switch (language)
{
case Language.English:
return new EnglishSpeaker();
case Language.German:
return new GermanSpeaker();
case Language.Spanish:
return new SpanishSpeaker();
default:
throw new ApplicationException("No speaker can speak such language");
}
}
}
class Program
{
[STAThread]
static void Main()
{
//This is your client code.
ISpeaker speaker = SpeakerFactory.CreateSpeaker(Language.English);
speaker.Speak();
Console.ReadLine();
}
}
public interface ISpeaker
{
void Speak();
}
public abstract class Speaker : ISpeaker
{
#region ISpeaker Members
public abstract void Speak();
public virtual void SayHello()
{
Console.WriteLine("Hello world.");
}
#endregion
}
public class EnglishSpeaker : Speaker
{
public EnglishSpeaker() { }
#region ISpeaker Members
public override void Speak()
{
this.SayHello();
Console.WriteLine("I speak English.");
}
#endregion
}
public class GermanSpeaker : Speaker
{
public GermanSpeaker() { }
#region ISpeaker Members
public override void Speak()
{
Console.WriteLine("I speak German.");
this.SayHello();
}
#endregion
}
public class SpanishSpeaker : Speaker
{
public SpanishSpeaker() { }
#region ISpeaker Members
public override void Speak()
{
Console.WriteLine("I speak Spanish.");
}
public override void SayHello()
{
throw new ApplicationException("I cannot say Hello World.");
}
#endregion
}
<イグ
関連
-
[解決済み] 抽象メソッドと仮想メソッドの違いは何ですか?
-
[解決済み] なぜList<T>を継承しないのですか?
-
[解決済み] インターフェースと抽象クラス(一般的なOO)
-
[解決済み] インターフェースとベースクラス
-
[解決済み] Java のコア・ライブラリにおける GoF デザイン・パターンの例
-
[解決済み] C#のインターフェイス。暗黙の実装と明示の実装
-
[解決済み】関数型プログラミングはGoFデザインパターンに取って代わるか?
-
[解決済み】「インターフェースに合わせたプログラム」とはどういう意味ですか?
-
[解決済み】「結合度が低く、結合度が高い」とはどういう意味ですか?
-
[解決済み] メソッドチェイニング - なぜ良い習慣なのか、そうでないのか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] メソッドと関数の違いは何ですか?
-
[解決済み] インターフェースと抽象クラスの違いは何ですか?
-
[解決済み】「インターフェースに合わせたプログラム」とはどういう意味ですか?
-
[解決済み】依存関係逆転の原則とは何ですか、なぜそれが重要なのですか?
-
[解決済み】コンストラクターとファクトリーメソッドの比較【終了しました
-
[解決済み] ProxyパターンとDecoratorパターンの違い
-
[解決済み] メソッドチェイニング - なぜ良い習慣なのか、そうでないのか?
-
[解決済み] Delegateとは?[クローズド]。
-
[解決済み] コンストラクタをprivateにするとどうなるのですか?
-
[解決済み] nullを返すのは設計ミス?[クローズド]