程序员为什么要将实现与接口分开?


18

桥接设计模式将实现与程序界面分开。

为什么这有优势?


为防止泄漏抽象
SK-logic

1
这似乎已经为每个人所理解,但是对于新的观看者来说,Bridge Design并不是关于“程序”的实现和接口,而是程序的某些部分甚至是很小的部分。整个程序将是接口和实现的集合(每个接口具有一个或多个实现)。第一句话可能应该是:“桥接设计模式将接口及其实现在所有源代码中分开。”
RalphChapin 2012年

Answers:


35

它允许您独立于接口更改实现。这有助于应对不断变化的需求。

经典示例是用更大,更好,更快,更小或更其他方式替换界面下的存储实现,而不必更改系统的其余部分。


23

除了丹尼尔的答案外,通过多态性之类的概念将接口与实现分开,还可以创建同一接口的多个实现,这些实现以不同的方式完成相似的工作。

例如,许多语言在标准库中的某个地方都有的概念。流是保存用于串行访问的数据的东西。它具有两个基本操作:读取(从流中加载下一个X字节字节)和写入(向流中添加X字节数据字节),有时第三个操作是,Seek(重置流的“当前位置”)移至新位置)。

这是一个非常简单的概念,但是请考虑使用它可以做的所有事情。最明显的一种是与光盘上的文件进行交互。文件流可让您从文件中读取数据或对其进行写入。但是,如果您想通过网络连接发送数据怎么办?

如果直接依赖于实现,则必须写出两个完全不同的例程,以将相同数据保存到文件中或通过网络发送。但是,如果您有一个流接口,则可以为其创建两个不同的实现(FileStreamNetworkStream),以封装将数据发送到所需位置的特定细节,然后只需要编写一次保存文件的代码即可。 。突然,您SaveToFileSendOverNetwork例程变得简单了很多:它们只是设置了适当类型的流,并将其传递给SaveData接受流接口的例程-不需要关心什么类型,只要它可以执行写入操作-并将数据保存到流中。

这也意味着,如果您的数据格式发生更改,则不必在多个不同的位置进行更改。如果将数据保存代码集中在一个需要流的例程中,那么这是唯一需要更新的地方,因此当您需要更改两个地方时,只需更改一个地方就不会偶然引入错误。因此,将接口与实现分开,并使用多态性使代码更易于阅读和理解,并且更不会出现错误。


1
这是OOP的最强功能之一。我就是喜欢...
Radu Murzea 2012年

1
使用普通接口的这种形式有何不同?
vainolo

@Vainolo:它有助于代码重用。即使您有多种类型的流,它们彼此也会做很多相同的事情。如果从IStream接口开始,则必须为每个流重新创建整个功能集。但是,如果您从基本抽象流类开始,则它可以容纳所有公共状态和功能,然后让后代实现独特的功能。
梅森惠勒2013年

2
@RaduMurzea这不是特定于OOP的。类型类让您以完全非OOP的方式执行相同的操作。
2013年

@Wes完全一样,只是想说同样的话,然后我读了您的评论。
jhegedus

4

尽管它们是相关的,但实际上您确实有两个非常不同的问题。

标题中的问题是比较笼统的问题,为什么您通常要将接口与实现分开?第二个问题是为什么桥接模式有用。它们之所以相关,是因为桥接模式是将接口与实现分开的一种特定方式,同时也会带来其他一些特定后果。

对于每个程序员来说,普遍的问题都是至关重要的。这是防止程序更改传播到任何地方的原因。我无法想象人类不使用它就能编程。

当您用编程语言编写一个简单的加法语句时,这已经是一种抽象(即使没有使用运算符重载来添加矩阵或类似的东西)也要经过很多其他代码才能最终执行在计算机中的电路上。如果接口(例如“ 3 + 5”)与实现(一堆机器代码)之间没有分离,那么每次实现更改时都必须更改代码(例如,您想在新处理器)。

即使在简单的CRUD应用程序中,从广义上讲,每个方法签名都是其实现的接口。

所有这些抽象都具有相同的基本目标-使调用代码以最抽象的方式表达其意图,从而为实现者提供所需的尽可能多的信息。这样可以在它们之间提供最小的耦合,并在需要尽可能多地更改代码时限制了纹波效应。

这听起来很简单,但实际上却变得复杂。

桥接模式是将实现的某些位分离为接口的一种特定方式。模式的类图比描述内容更丰富。与桥接相比,它更像是具有可插入模块的方式,但他们将其命名为桥接,因为它通常用于在接口之前创建模块的位置。因此,为类似的现有实现创建通用接口可以“弥合”差异,并允许您使用任何实现进行编码。

因此,假设您想为一个文字处理器编写一个插件,但是您希望它可以在多个文字处理器上工作。您可能会创建一个接口,该接口抽象出所需的基于文字处理器的功能(并且每个文字处理器都必须可以实现这些功能,因为您无法更改这些功能),并且要为每个要支持的文字处理器提供该接口的一个实现者。然后,您的应用程序可以调用该接口,而不必担心每个字处理器的详细信息。

它实际上比这稍微详细一点,因为每个类实际上可能是一个类层次结构(因此,可能不仅有一个抽象的文字处理程序,而且还有一个抽象的Document,抽象的TextSelection等,每个都有具体的实现),但是同样的想法。

有点像外观,只是在这种情况下,抽象层专注于为多个底层系统提供相同的接口。

它与控制反转有关,因为具体的实现者将传递给方法或构造函数,并确定所调用的实际实现。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.