“针对接口编程,而不是实现”是什么意思?

2024-01-02

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

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


接口只是合同或签名,他们不知道 关于实施的任何事情。

针对接口进行编码意味着,客户端代码始终保存由工厂提供的接口对象。工厂返回的任何实例都是 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基类。在本次更新中,我为所有扬声器添加了一个功能“SayHello”。所有发言者都会说“Hello World”。这是具有相似功能的共同特征。参考类图你会发现Speaker抽象类实现ISpeaker接口并标记Speak()作为抽象,这意味着每个发言者实现负责实现Speak()方法,因为它不同于Speaker to Speaker。但所有发言者都一致说“你好”。因此,在抽象的Speaker类中,我们定义了一个方法来表示“Hello World”,并且每个Speaker实施将得出SayHello() method.

考虑一个情况SpanishSpeaker无法打招呼,因此在这种情况下您可以覆盖SayHello()西班牙语使用者的方法并提出适当的例外。

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

我们可以通过简单地添加一个基本抽象类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
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

“针对接口编程,而不是实现”是什么意思? 的相关文章

  • C++ 包装类的设计

    我必须使用一个界面非常笨拙的旧类 由于我无法更改它并且依赖它 因此我想构建一个包装器 提供一个干净的界面 假设我有课笨手笨脚的班级 基本上 我有三种方法 1 参考会员 Class Wrapper public Wrapper ClumsyC
  • Mootools 使用“extend”方法扩展“Function”类,导致 jQuery 无法使用

    Mootools 扩展了 Function 类 并在其中添加了一个名为 extend 的新方法 现在 jQuery 尝试使用 jQuery prototype extend 添加 扩展 功能 然而 由于 extend 已经是 jQuery
  • 界面与组合

    我想我理解接口和抽象之间的区别 抽象设置默认行为 在纯抽象的情况下 行为需要由派生类设置 接口是您所需要的 无需基类的开销 那么接口相对于组合的优势是什么 我能想到的唯一优点是在基类中使用受保护的字段 我缺少什么 你的标题没有意义 你的解释
  • 将国际象棋引擎连接到用 Javascript 制作的现有 GUI

    我编写了自己的用于下棋和教授国际象棋的 GUI GUI 是使用 HTML 编写的 用于外观 使用 JavaScript 来实现各个部件的行为 目前该程序不遵循任何国际象棋规则 正确遵循国际象棋规则取决于用户 这允许自由地设置非法位置或多次移
  • 在 C++ 中什么时候应该使用“friend”?

    我一直在阅读C FAQ http yosefk com c fqa 并且很好奇friend http yosefk com c fqa friend html宣言 我个人从未使用过它 但我有兴趣探索该语言 使用的一个很好的例子是什么frie
  • 继承接口方法的重新实现

    我不完全理解如何使用接口 所以我必须问 我使用 BaseClass 它实现了 IBaseClass 接口 这些接口仅包含一个声明 public interface IBaseClass void Refresh 所以我在我的 Basecla
  • 依赖注入系统中的事件朝哪个方向发展?

    上或下 我是一个非常注重视觉的人 我将我的应用程序视为一个层次结构 顶部是根 底部是叶子 我还了解到 在 DI 系统中 容器不知道其所包含对象的职责 功能 相反 所包含的对象知道它们的上下文 因为上下文 依赖项 被注入 UP 非 DI 方式
  • C# 中的抽象类和接口类有什么不同?

    C 中的抽象类和接口类有什么不同 An 接口不是类 它只是一个contract定义了public一个类的成员must实施 抽象类只是一个类 您从中可以cannot创建一个实例 通常您会使用它来定义一个基类 该基类定义了一些virtual方法
  • 让按钮更容易点击

    我有一个按钮 在某些手机上由于尺寸太大而很难点击 但让它变大会破坏布局 可以向视图解释它有一个比其可见区域更大的 点击框 吗 不确定这是否有帮助 如果您使用没有背景的 ImageButton 并设置 Padding 值 您的按钮将具有更大的
  • Pylance:“property”与“int”不兼容

    from typing extensions import Protocol class IFoo Protocol value int class Foo IFoo property def value self gt int retur
  • 我可以在 Laravel 5.2 中创建一个继承自 User 的新类吗?

    我对 Laravel 还很陌生 使用的是迄今为止的最新版本 5 2 因此我遇到了以下困境 我知道 Laravel 附带了一个User开箱即用的类 但我想开发一个系统 在其中我可以有另外两种类型的用户 称为Researcher and Adm
  • Android proguard Javascript 接口问题

    我的项目在使用 proguard 进行混淆后因 javascriptinterface 失败 这是包含混淆器配置的一些建议的链接 但它在我的情况下不起作用 http groups google com group android devel
  • 列出某个类的所有对象

    好的 我的问题如下 我有一个用这个构造函数描述宠物的类 public function construct name type age 所以我想做的是制作一些宠物对象 然后我想打印这个类的所有对象的所有属性 这样它看起来像this http
  • 参考接口创建对象

    引用变量可以声明为类类型或接口类型 如果变量声明为接口类型 则它可以引用实现该接口的任何类的任何对象 根据上面的说法我做了一个理解上的代码 正如上面所说声明为接口类型 它可以引用实现该接口的任何类的任何对象 但在我的代码中显示display
  • 具有不同返回类型的 C# 通用接口

    我有可以返回多种格式数据的网络服务 例如 json 和 xml 我正在针对此 Web 服务构建一个简单的 C api 我希望这些方法能够从 json 原始 json 或原始 xml 返回完全序列化的对象 例如 List
  • C# 中 getter 和 setter 的接口

    当我读到这里时http msdn microsoft com en us library 75e8y5dd 28v VS 100 29 aspx http msdn microsoft com en us library 75e8y5dd
  • 服务作为 SOA 中的中介

    我知道什么是 通常的 中介设计模式 维基百科中有一些描述 http en wikipedia org wiki Mediator pattern http en wikipedia org wiki Mediator pattern 在我的
  • 可插入错误处理策略[关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我有服务对象 服务 A 它有一些特定的重复异步任务 该服务对象还有一个监督对象 服务B 我想处理与服务 A 中特定任务相关的大部分错误
  • 工厂模式和策略模式

    我需要创建一个类来负责结果集处理 但可能会发生应该使用不同的算法来处理该结果集的情况 我知道以下选项 1 使用策略模式 伪代码如下 interface Strategy processResultSet ResultSet rs class
  • Java:SortedMap、TreeMap、可比较?如何使用?

    我有一个对象列表 需要根据其中一个字段的属性进行排序 我听说 SortedMap 和 Comparator 是实现此目的的最佳方法 我是否要与正在排序的类实现 Comparable 还是创建一个新类 如何实例化 SortedMap 并传入

随机推荐