Jam*_*mes 162

"适配器使它们在设计之后工作; Bridge使它们在它们工作之前工作.[GoF,p219]"

实际上,适配器模式在您拥有现有代码时非常有用,无论是第三方还是内部,但是您无法控制,或者无法更改以满足您需要的界面.例如,我们有一个SuperWeaponsArray可以控制一系列精美的世界末日设备.

public class SuperWeaponsArray {
  /*...*/

  public void destroyWorld() {
    for (Weapon w : armedWeapons) {
      w.fire();
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

大.除了我们意识到我们的武器库中有一个核装置,它早于转换到武器界面.但我们真的很喜欢它在这里工作......所以我们做了什么......楔入它!

NukeWeaponsAdaptor - 基于我们的Nuke类,但导出Weapon接口.甜蜜,现在我们肯定会摧毁这个世界.它看起来像是一块垃圾,但它让事情变得有效.


大桥的图案是你实现了前面-如果你知道你有两个正交的层次结构,它提供了一种分离的界面并以这样的方式,你没有得到的类的疯狂数量的实施.假设你有:

MemoryMappedFile和DirectReadFile类型的文件对象.假设您希望能够从各种来源读取文件(可能是Linux与Windows实现等).Bridge帮助您避免因:

MemoryMappedWindowsFile MemoryMappedLinuxFile DirectReadWindowsFile DirectReadLinuxFile

  • @omouse upvoted,示例*代码*实际上不是这个答案的重点.对于细心的读者来说,有足够的指针来开始区分模式,所以总而言之 - 它*是一个很好的答案. (32认同)
  • 你能为桥模式提供一些实际的代码示例吗? (15认同)
  • downvoted,你能使用更抽象的代码清单吗?这个例子太具体了,令人困惑. (7认同)
  • *“适配器在设计之后使事情起作用;Bridge使它们在设计之前起作用。”*在我读过的书中根本没有指定,因此很难区分两者。我想阅读GOF毕竟是值得的...... (3认同)
  • 我想很多人都以同样的方式来到这个问题 - 他们可能已经在寻找这两种模式的代码,但他们认识到了一些相似之处,并意识到他们的理解可以通过并置两种模式来进一步巩固.有关桥梁帮助您避免使用Windows和Linux特定文件的问题,至少在我看来,有助于理解Bridge Pattern的"实施者"(http://www.dofactory.com/net/bridge-design-) pattern)与"Adapter"不同. (2认同)

Jef*_*cox 13

http://en.wikipedia.org/wiki/Adapter_pattern

适配器模式更多的是让您的现有代码与更新的系统或接口一起使用.

如果您有一组公司标准的Web服务API,您希望将其提供给另一个应用程序的现有可扩展性接口,您可以考虑编写一组适配器来执行此操作.请注意,有一个灰色区域,这更多是关于技术上如何定义模式,因为其他模式如外观是相似的.

http://en.wikipedia.org/wiki/Bridge_pattern

Bridge模式将允许您可能具有算法或系统的替代实现.

虽然不是经典的Bridge模式示例,但想象一下,如果你有一些数据存储的实现:一个在空间有效,另一个在原始性能方面有效......并且你有一个商业案例可以在你的应用程序或框架中提供.

就你的问题而言,"我可以使用哪种模式",答案是,只要它对你的项目有意义!也许考虑提供澄清编辑,以指导您认为需要使用其中一个的讨论.


Rav*_*abu 11

适配器:

  1. 这是一种结构模式
  2. 使用两个不兼容的接口很有用

UML图:来自dofactory文章:

在此输入图像描述

目标 :定义客户端使用的特定于域的接口.

适配器:使接口Adaptee适应Target接口.

Adaptee:定义需要适应的现有界面.

客户端 :与符合Target接口的对象协作.

例:

Square和Rectangle是两种不同的形状,每个都需要不同的方法.但仍然Square工作在Rectangle接口上,转换了一些属性.

public class AdapterDemo{
    public static void main(String args[]){
        SquareArea s = new SquareArea(4);
        System.out.println("Square area :"+s.getArea());
    }
}

class RectangleArea {
    public int getArea(int length, int width){
        return length * width;
    }
}

class SquareArea extends RectangleArea {

    int length;
    public SquareArea(int length){
        this.length = length;
    }
    public int getArea(){
        return getArea(length,length);
    }
}
Run Code Online (Sandbox Code Playgroud)

桥:

  1. 这是结构模式
  2. 它将抽象与其实现分离,两者都可以独立变化
  3. 这是可能的,因为组合已被用来代替继承

编辑:(根据@quasoft建议)

这种模式中有四个组件.

  1. 抽象:它定义了一个接口

  2. RefinedAbstraction:它实现了抽象:

  3. 实现者:它定义了一个实现接口

  4. ConcreteImplementor:它实现了Implementor接口.

代码段:

Gear gear = new ManualGear();
Vehicle vehicle = new Car(gear);
vehicle.addGear();

gear = new AutoGear();
vehicle = new Car(gear);
vehicle.addGear();
Run Code Online (Sandbox Code Playgroud)

相关文章:

你什么时候使用桥模式?它与适配器模式有何不同?

主要差异:源于制作文章

  1. 适配器在设计完成后使其工作; Bridge让它们在它们之前工作.
  2. Bridge是预先设计的,让抽象和实现独立变化.改造适配器以使不相关的类一起工作.


jac*_*646 11

在最上面的答案中,@James 引用了 GoF 第 219 页的一句话。我认为值得在这里复制完整的解释。

适配器与桥接器

适配器模式和桥接模式有一些共同的属性。两者都通过为另一个对象提供一定程度的间接性来提高灵活性。两者都涉及从该对象自己的接口以外的接口转发请求到该对象。

这些模式之间的主要区别在于它们的意图。适配器专注于解决两个现有接口之间的不兼容性。它不关注这些接口是如何实现的,也不考虑它们如何独立发展。这是一种使两个独立设计的类一起工作而无需重新实现其中一个的方法。另一方面,桥接了一个抽象及其(可能有很多)实现。它为客户端提供了一个稳定的接口,即使它允许您改变实现它的类。随着系统的发展,它还适应新的实现。

由于这些差异,Adapter 和 Bridge 通常在软件生命周期的不同阶段使用。当您发现两个不兼容的类应该一起工作时,通常需要使用适配器,通常是为了避免复制代码。这种耦合是不可预见的。相反,桥的用户预先理解抽象必须有多个实现,并且两者都可以独立发展。适配器模式使设计完成后可以正常工作;Bridge 让他们先于工作。这并不意味着 Adapter 在某种程度上不如 Bridge;而是意味着 Adapter 在某种程度上不如 Bridge。每种模式仅解决不同的问题。


小智 8

这篇文章已经存在了很长一段时间.但是,重要的是要理解外观有点类似于适配器,但它并不完全相同.适配器将现有类"调整"为通常不兼容的客户端类.假设您有一个旧的工作流系统,您的应用程序将其用作客户端.您的公司可能会使用新的"不兼容"(在接口方面)替换工作流程系统.在大多数情况下,您可以使用适配器模式并编写实际调用新工作流引擎接口的代码.桥通常以不同的方式使用.如果您实际上有一个需要使用不同文件系统的系统(即本地磁盘,NFS等),您可以使用桥接模式并创建一个抽象层来处理所有文件系统.这基本上是桥模式的简单用例.Facade和适配器确实共享一些属性但是外观通常用于简化现有的接口/类.在EJB的早期阶段,没有对EJB的本地调用.开发人员总是获得存根,将其缩小并称之为"伪远程".这常常导致性能问题(尤其是当真正通过电线调用时).经验丰富的开发人员将使用Facade模式为客户端提供非常粗粒度的界面.然后,这个外观将对不同的更细粒度的方法进行多次调用.总而言之,这大大减少了所需的方法调用次数并提高了性能.


Vov*_*ova 5

根据此处的另一个 stackoverflow 答案,对我来说,这似乎是更短、更清晰的答案:

  • 当您有一个抽象接口,并且您希望将该接口映射到另一个具有类似功能角色但接口不同的对象时,请使用适配器。

  • Bridge与 Adapter 非常相似,但是当您定义抽象接口和底层实现时,我们将其称为 Bridge。也就是说,您不适应某些遗留或第三方代码,您是所有代码的设计者,但您需要能够交换不同的实现。