什么是“编程接口,而不是实现"?意思是? [英] What does "program to interfaces, not implementations" mean?

查看:27
本文介绍了什么是“编程接口,而不是实现"?意思是?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在阅读有关设计模式的内容时,会偶然发现这句话.

One stumbles upon this phrase when reading about design patterns.

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

But I don't understand it, could someone explain this for me?

推荐答案

接口只是合同或签名,他们不知道任何关于实现的信息.

针对接口编码意味着,客户端代码总是持有一个由工厂提供的接口对象.工厂返回的任何实例都属于任何工厂候选类必须实现的接口类型.这样客户端程序就不用担心实现了,接口签名决定了所有的操作可以做什么.这可用于在运行时更改程序的行为.从维护的角度来看,它还可以帮助您编写更好的程序.

Coding against interface means, the client code always holds an Interface object which is supplied by a factory. Any instance returned by the factory would be of type Interface which any factory candidate class must have implemented. This way the client program is not worried about implementation and the interface signature determines what all operations can be done. This can be used to change the behavior of a program at run-time. It also helps you to write far better programs from the maintenance point of view.

这是一个基本的例子.

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
}

这只是一个基本的例子,原理的实际解释是超出了本答案的范围.

编辑

我已经更新了上面的例子并添加了一个抽象的 Speaker 基类.在本次更新中,我为SayHello"的所有扬声器添加了一项功能.所有演讲者都说Hello World".所以这是一个具有相似功能的共同特征.参考类图,你会发现Speaker抽象类实现了ISpeaker接口并将Speak()标记为抽象,这意味着每个 Speaker 实现负责实现 Speak() 方法,因为它从 SpeakerSpeaker 变化.但所有发言者都一致地说你好".因此,在抽象的 Speaker 类中,我们定义了一个表示Hello World"的方法,并且每个 Speaker 实现都将派生出 SayHello() 方法.

EDIT

I have updated the example above and added an abstract Speaker base class. In this update, I added a feature to all Speakers to "SayHello". All speaker speak "Hello World". So that's a common feature with similar function. Refer to the class diagram and you'll find that Speaker abstract class implement ISpeaker interface and marks the Speak() as abstract which means that the each Speaker implementation is responsible for implementing the Speak() method since it varies from Speaker to Speaker. But all speaker say "Hello" unanimously. So in the abstract Speaker class we define a method that says "Hello World" and each Speaker implementation will derive the SayHello() method.

考虑 SpanishSpeaker 无法 Say Hello 的情况,因此在这种情况下,您可以覆盖西班牙语演讲者的 SayHello() 方法并引发适当的异常.

Consider a case where SpanishSpeaker cannot Say Hello so in that case you can override the SayHello() method for Spanish Speaker and raise proper exception.

请注意,我们有未对界面进行任何更改I扬声器.和客户端代码和SpeakerFactory 也不受影响不变.这就是我们通过编程到接口实现的目标.

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 实现中进行一些小的修改来实现这种行为,从而保持原始程序不变.这是任何应用程序都需要的功能,它使您的应用程序易于维护.

And we could achieve this behavior by simply adding a base abstract class Speaker and some minor modification in Each implementation thus leaving the original program unchanged. This is a desired feature of any application and it makes your application easily maintainable.

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
}

这篇关于什么是“编程接口,而不是实现"?意思是?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆