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

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

问题描述



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

解决方案


接口只是合同或签名,他们不知道
有关实现的任何内容。 / strong>


对接口意味着编码,客户端代码始终保存由工厂提供的Interface对象。工厂返回的任何实例都将是任何工厂候选类必须实现的Interface类型。这样客户端程序不用担心实现,而接口签名决定了所有的操作都可以完成。这可以用于在运行时更改程序的行为。



这是一个基本的例子。



它可以帮助您从维护的角度编写更好的程序。

  public enum Language 
{
英文,德文,西班牙文
}

public class SpeakerFactory
{
public static ISpeaker CreateSpeaker(语言语言)
{
switch(language)
{
case Language.English:
return new EnglishSpeaker();
case Language.German:
return new GermanSpeaker();
case Language.Spanish:
return new SpanishSpeaker();
默认值:
抛出新的ApplicationException(没有说话者可以说这样的语言);
}
}
}

[STAThread]
static void Main()
{
//这是你的客户端码。
ISpeaker speaker = SpeakerFactory.CreateSpeaker(Language.English);
speaker.Speak();
Console.ReadLine();
}

public interface ISpeaker
{
void Speak();
}

public class EnglishSpeaker:ISpeaker
{
public EnglishSpeaker(){}

#region ISpeaker成员

public void Speak()
{
Console.WriteLine(我会说英语);
}

#endregion
}

public class GermanSpeaker:ISpeaker
{
public GermanSpeaker(){}

#region ISpeaker成员

public void Speak()
{
Console.WriteLine(我说德语);
}

#endregion
}

public class SpanishSpeaker:ISpeaker
{
public SpanishSpeaker(){}

#region ISpeaker成员

public void Speak()
{
Console.WriteLine(我说西班牙语);
}

#endregion
}

< a href =http://ruchitsurati.net/myfiles/interface.png> alt text http://ruchitsurati.net/myfiles/interface.png


这仅仅是一个基本的例子,而
的实际解释原则是
超出了这个答案的范围。




编辑



我已经更新了上面的例子,并添加了一个抽象的Speaker基类。在这个更新中,我向所有Spakers添加了一个SayHello功能。所有的演讲者都会说Hello World。这是一个具有类似功能的常见功能。参考类图,你会发现Speaker抽象类实现ISpeaker接口并将Speak()标记为抽象,这意味着每个Speaker实现负责实现Speak方法,因为它从扬声器到扬声器不同。但是所有的演讲者都一致地说你好。所以在抽象的Speaker类中,我们定义了一个Hello World的方法,每个Speaker的实现都将得到SayHello方法。



考虑一个西班牙语Speaker不能说Hello的情况在这种情况下,您可以覆盖西班牙语Speaker的SayHello方法,并提出正确的例外。


请注意,我们有
没有对Interface
ISpeaker进行任何更改。客户端代码和
SpeakerFactory也保持不受影响
不变。而这正是我们通过<编程接口实现的。


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

  public enum Language 
{
英语,德语,西班牙语
}

public class SpeakerFactory
{
public static ISpeaker CreateSpeaker(Language language)
{
开关(语言)
{
case Language.English:
return new EnglishSpeaker();
case Language.German:
return new GermanSpeaker();
case Language.Spanish:
return new SpanishSpeaker();
默认值:
抛出新的ApplicationException(没有说话者可以说这样的语言);
}
}
}

类程序
{
[STAThread]
static void Main()
{
//这是您的客户端代码。
ISpeaker speaker = SpeakerFactory.CreateSpeaker(Language.English);
speaker.Speak();
Console.ReadLine();
}
}

public interface ISpeaker
{
void Speak();
}

public abstract class演讲者:ISpeaker
{

#region ISpeaker成员

public abstract void Speak() ;

public virtual void SayHello()
{
Console.WriteLine(Hello world。);
}

#endregion
}

public class EnglishSpeaker:Speaker
{
public EnglishSpeaker(){}

#region ISpeaker成员

public override void Speak()
{
this.SayHello();
Console.WriteLine(我会说英语);
}

#endregion
}

public class GermanSpeaker:Speaker
{
public GermanSpeaker(){}

#region ISpeaker成员

public override void Speak()
{
Console.WriteLine(我会说德语);
this.SayHello();
}

#endregion
}

public class SpanishSpeaker:Speaker
{
public SpanishSpeaker(){}

#region ISpeaker成员

public override void Speak()
{
Console.WriteLine(我说西班牙语);
}

public override void SayHello()
{
throw new ApplicationException(我不能说Hello World);
}

#endregion
}

< a href =http://demo.ruchitsurati.net/myfiles/interface1.png> alt text http://demo.ruchitsurati.net/myfiles/interface1.png


One stumbles upon this phrase when reading about design patterns.

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

解决方案

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

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.

Here's a basic example for you.

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 http://ruchitsurati.net/myfiles/interface.png

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

EDIT

I have updated the example above and added an abstract Speaker base class. In this update, I added a feature to all Spakers 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.

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.

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.

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
}

alt text http://demo.ruchitsurati.net/myfiles/interface1.png

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

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