oop - "program to interfaces, not implementations"是什么意思?

标签 oop design-patterns interface software-design ooad

人们在阅读设计模式时偶然发现了这句话。

但是我不明白,有人可以帮我解释一下吗?

最佳答案

Interfaces are just contracts or signatures and they don't know anything about implementations.

针对接口(interface)进行编码意味着,客户端代码始终保存由工厂提供的接口(interface)对象。工厂返回的任何实例都是 Interface 类型,任何工厂候选类都必须实现该类型。这样客户端程序就不用担心实现,接口(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
}

alt text

This is just a basic example and actual explanation of the principle is beyond the scope of this answer.

编辑

我更新了上面的示例并添加了一个抽象 Speaker 基类。在本次更新中,我为所有扬声器添加了一个功能“SayHello”。所有发言者都会说“Hello World”。这是具有相似功能的共同特征。引用类图,你会发现Speaker抽象类实现了ISpeaker接口(interface),并将Speak()标记为抽象,这意味着每个Speaker 实现都负责实现Speak() 方法,因为它随Speaker 的不同而不同。但所有发言者都一致说“你好”。因此,在抽象的Speaker类中,我们定义了一个表示“Hello World”的方法,并且每个Speaker实现都将派生出SayHello()方法。

考虑一下 SpanishSpeaker 无法 Say Hello 的情况,在这种情况下,您可以重写西类牙语扬声器的 SayHello() 方法并引发适当的异常。

Please note that, we have not made any changes to Interface ISpeaker. And the client code and SpeakerFactory also remain unaffected unchanged. And this is what we achieve by Programming-to-Interface.

我们可以通过简单地添加一个基本抽象类Speaker 并在Each 实现中进行一些小的修改来实现此行为,从而保持原始程序不变。这是任何应用程序都需要的功能,它使您的应用程序易于维护。

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
}

alt text

关于oop - "program to interfaces, not implementations"是什么意思?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2697783/

相关文章:

php - 我如何从父类的方法中动态更改对象的类?

oop - perl6 bless和new之间的区别

c++ - 何时使用 OOP 而不是数组

objective-c - 委托(delegate)引用它作为委托(delegate)的对象是否是一种不好的做法?

python - 在 Python 中使用命令模式执行/撤消

c++ - c和c++混合

arrays - Golang 将 interface{} 转换为 N 大小的数组

C++:具有用户定义类型的构造函数

java - 如何通过 Eclipse Selection Service 处理来自不同提供商的选择,同时保持松散耦合?

.net - .config 到构造函数的技巧?