桥接模式是否将抽象与实现分离?

时间:2016-01-29 08:08:34

标签: java design-patterns abstraction bridge

我从不同的文章中学习了Bridge模式,并根据我的理解实现了这一点。令我困惑的一件事是桥模式说

BridgePattern将抽象与其实现分离,以便两者可以独立变化

这句话是什么意思?实现是在单独的jar中吗?

独立声明的含义是什么?

考虑提供的journaldev文章,详细说明答案。

非常感谢任何帮助。

3 个答案:

答案 0 :(得分:26)

BridgePattern 将抽象与其实现分离

抽象实现可以独立变化,因为具体类不直接实现抽象(接口)

UML Diagram from Wikipedia

主要提示: 使用两个正交的类层次结构抽象层次结构 y和实施层次结构)组合(而不是继承)。这种组合有助于两个层次结构独立变化。

实施永远不会引用抽象。抽象包含实现接口作为成员(通过组合)。

回到journaldev文章中关于示例代码的问题:

形状抽象

三角形 RedefinedAbstraction

颜色为执行者

RedColor是 ConcreteImplementor

具体的 Shape 对象: Triangle 扩展 Shape 但不实现 Color 接口。

public class Triangle extends Shape{
}

RedColor GreenColor 实际上实现了 Color 界面。

Concrete Shape对象( Triangle )独立于实现抽象(即 Color 接口)。

Shape tri = new Triangle(new RedColor());

此处三角形包含具体的颜色对象(构图)。如果颜色抽象(界面)发生变化, RedColor GreenColor 负责实现颜色的抽象 interface。

Shapes (如 Triangle )不受 Color 界面合约更改的影响。因此 Color 界面可以独立变化。这是可能的,因为 Shape 包含使用组合而非实施的合同。

摘要,

  1. 桥梁是一种结构模式
  2. 抽象和实现未在编译时绑定
  3. 抽象和实施 - 两者都可以在不影响客户的情况下发生变化
  4. 在以下情况下使用Bridge模式:

    1. 您需要实现的运行时绑定,
    2. 您从耦合接口和众多实现中获得了大量的类,
    3. 您希望在多个对象之间共享实现,
    4. 您需要映射正交类层次结构。
    5. 有用的链接:

      tutorialspoint artice

      dzone文章

      oodesign文章

      sourcemaking文章

      相关文章:

      When do you use the Bridge Pattern? How is it different from Adapter pattern?

答案 1 :(得分:4)

这个语句只是意味着你可以在运行时切换到抽象点所指向的实现者,一切都应该有效(比如在战略模式中;但在战略模式中,只有策略是抽象的)。 它也可以被理解为将两个类分开,这样他们就不必只知道彼此的接口了。

答案 2 :(得分:0)

对我而言,Bridge并不是GOF圣经中最重要的DP,因为它主要是战略的衍生物。由于一些其他模式没有很好地老化(工厂方法?),它意味着更多的继承与抽象类保持行为比其他模式,因此不太普遍适用。

主要是战略在做大工作,但战略的一个主要问题是战略经常需要有关其背景的知识。

在某些语言中,这导致策略被声明为上下文的朋友,或者在Java中定义为内部类的策略。

这意味着上下文通常最终会知道各种具体策略的存在。您可以通过使用setStrategy()函数来避免这种情况,但由于效率原因(您希望直接操纵上下文的数据结构),从具体策略到上下文的反向依赖通常会存活下来。

这个问题有点被Bridge解决,因为策略的上下文现在是抽象的,但仍然是一个先验的类,因为它至少具有策略的代码。它通常应该定义一个足以使用具体策略的访问API,可能带有漏洞,即抽象方法。你在AbstractStragey的操作签名中放置了一个AbstractContext,你很好。

因此,在我看来,Bridge通过使Context具有足够的策略来完成策略,但仍然足够抽象,以便可以正确地改进w.r.t.具体策略(在实现具体策略实际使用的上下文的抽象API时具有反馈效果)。

更简单的看待桥的方法是说AbstractStrategy操作应该始终将抽象作为参数,而不是真正了解它们的上下文。

更准确地回答OP问题:

  

这句话是什么意思?实现是在单独的jar中吗?

是的,的确,通常你可以在一个包" base"中定义抽象和实现者。 (可能是接口)。具体的实现者可以各自驻留在一个包" implXX"中。具体上下文可以驻留在单独的包中,并且#34; contXX"。依赖图中没有循环,每个人都依赖于base,new" contXX"和" implXX"可以独立定义(它们之间根本没有依赖关系),因此OP中的粗体语句。

  

独立声明的含义是什么?

想想eclipse中的编辑器插件;它必须处理按钮和点击上的操作(如策略),但策略需要做的实际操作是对编辑器状态本身起作用(例如"突出显示文本")。您可以以抽象的方式定义编辑器拥有的内容,包括它具有用于手抄本和按键的Handler以及突出显示和导航功能,甚至可以通过具体编辑器(闪存而不是突出显示)覆盖这些功能。这是一座桥梁,您可以独立定义新的编辑器和新的处理程序。

通过一些依赖注入(例如Google guice)或一些手动工厂代码或组件方向来从外部干净地设置策略,您可以获得应用程序各个部分的非常低的耦合。

  

考虑提供的journaldev文章,详细说明答案。

老实说,我认为这不是DP的最佳应用,因为Color实现似乎并不关心它们的上下文。你应该在这里使用装饰器,因为Color是Shape的一个独立问题。

看一下这些幻灯片,找一个装饰器的解决方案(部分用法语,对不起)。 https://www-licence.ufr-info-p6.jussieu.fr/lmd/licence/2015/ue/3I002-2016fev/cours/cours-9.pdf(幻灯片16-18)基于此处介绍的示例: https://www-licence.ufr-info-p6.jussieu.fr/lmd/licence/2015/ue/3I002-2016fev/cours/cours-4.pdf 幻灯片10到15。

在这个例子中,我们需要Bridge if" updateInertie"是Forme的成员,这听起来并不荒谬。 Bridge再次成为其他模式的组合。