桥接设计模式将实现与程序界面分开。
为什么这有优势?
桥接设计模式将实现与程序界面分开。
为什么这有优势?
Answers:
除了丹尼尔的答案外,通过多态性之类的概念将接口与实现分开,还可以创建同一接口的多个实现,这些实现以不同的方式完成相似的工作。
例如,许多语言在标准库中的某个地方都有流的概念。流是保存用于串行访问的数据的东西。它具有两个基本操作:读取(从流中加载下一个X字节字节)和写入(向流中添加X字节数据字节),有时第三个操作是,Seek(重置流的“当前位置”)移至新位置)。
这是一个非常简单的概念,但是请考虑使用它可以做的所有事情。最明显的一种是与光盘上的文件进行交互。文件流可让您从文件中读取数据或对其进行写入。但是,如果您想通过网络连接发送数据怎么办?
如果直接依赖于实现,则必须写出两个完全不同的例程,以将相同数据保存到文件中或通过网络发送。但是,如果您有一个流接口,则可以为其创建两个不同的实现(FileStream
和NetworkStream
),以封装将数据发送到所需位置的特定细节,然后只需要编写一次保存文件的代码即可。 。突然,您SaveToFile
和SendOverNetwork
例程变得简单了很多:它们只是设置了适当类型的流,并将其传递给SaveData
接受流接口的例程-不需要关心什么类型,只要它可以执行写入操作-并将数据保存到流中。
这也意味着,如果您的数据格式发生更改,则不必在多个不同的位置进行更改。如果将数据保存代码集中在一个需要流的例程中,那么这是唯一需要更新的地方,因此当您需要更改两个地方时,只需更改一个地方就不会偶然引入错误。因此,将接口与实现分开,并使用多态性使代码更易于阅读和理解,并且更不会出现错误。
IStream
接口开始,则必须为每个流重新创建整个功能集。但是,如果您从基本抽象流类开始,则它可以容纳所有公共状态和功能,然后让后代实现独特的功能。
尽管它们是相关的,但实际上您确实有两个非常不同的问题。
标题中的问题是比较笼统的问题,为什么您通常要将接口与实现分开?第二个问题是为什么桥接模式有用。它们之所以相关,是因为桥接模式是将接口与实现分开的一种特定方式,同时也会带来其他一些特定后果。
对于每个程序员来说,普遍的问题都是至关重要的。这是防止程序更改传播到任何地方的原因。我无法想象人类不使用它就能编程。
当您用编程语言编写一个简单的加法语句时,这已经是一种抽象(即使没有使用运算符重载来添加矩阵或类似的东西)也要经过很多其他代码才能最终执行在计算机中的电路上。如果接口(例如“ 3 + 5”)与实现(一堆机器代码)之间没有分离,那么每次实现更改时都必须更改代码(例如,您想在新处理器)。
即使在简单的CRUD应用程序中,从广义上讲,每个方法签名都是其实现的接口。
所有这些抽象都具有相同的基本目标-使调用代码以最抽象的方式表达其意图,从而为实现者提供所需的尽可能多的信息。这样可以在它们之间提供最小的耦合,并在需要尽可能多地更改代码时限制了纹波效应。
这听起来很简单,但实际上却变得复杂。
桥接模式是将实现的某些位分离为接口的一种特定方式。模式的类图比描述内容更丰富。与桥接相比,它更像是具有可插入模块的方式,但他们将其命名为桥接,因为它通常用于在接口之前创建模块的位置。因此,为类似的现有实现创建通用接口可以“弥合”差异,并允许您使用任何实现进行编码。
因此,假设您想为一个文字处理器编写一个插件,但是您希望它可以在多个文字处理器上工作。您可能会创建一个接口,该接口抽象出所需的基于文字处理器的功能(并且每个文字处理器都必须可以实现这些功能,因为您无法更改这些功能),并且要为每个要支持的文字处理器提供该接口的一个实现者。然后,您的应用程序可以调用该接口,而不必担心每个字处理器的详细信息。
它实际上比这稍微详细一点,因为每个类实际上可能是一个类层次结构(因此,可能不仅有一个抽象的文字处理程序,而且还有一个抽象的Document,抽象的TextSelection等,每个都有具体的实现),但是同样的想法。
有点像外观,只是在这种情况下,抽象层专注于为多个底层系统提供相同的接口。
它与控制反转有关,因为具体的实现者将传递给方法或构造函数,并确定所调用的实际实现。