1. ホーム
  2. oop

[解決済み] 実装ではなくインターフェースにプログラムする」とはどういう意味ですか?

2022-04-24 22:36:34

質問

デザインパターンについて読んでいると、このようなフレーズに出会います。

しかし、私には理解できないので、どなたか説明していただけませんか?

どのように解決するのですか?

<ブロッククオート

インターフェースは、単なる契約や署名であって 実装について何も知らない。

インターフェースに対するコーディングとは、クライアントコードが常にファクトリーから供給されるインターフェースオブジェクトを保持することを意味します。ファクトリーから返されるインスタンスは、ファクトリーの候補クラスが必ず実装している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
}

<イグ