桥接模式和适配器模式的区别

发布于 2024-08-04 22:57:26 字数 23 浏览 9 评论 0原文

桥接模式和适配器模式有什么区别?

What is the difference between the Bridge and Adapter patterns?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(10

拧巴小姐 2024-08-11 22:57:26

“适配器让设计后的东西发挥作用;桥让它们工作
在他们之前工作。 [GoF,p219]”

实际上,当您有现有代码(无论是第三方代码还是内部代码)但超出您的控制范围或无法更改以完全满足要求时,适配器模式非常有用。例如,我们有一个超级武器阵列,它可以控制一系列末日设备,

public class SuperWeaponsArray {
  /*...*/

  public void destroyWorld() {
    for (Weapon w : armedWeapons) {
      w.fire();
    }
  }
}

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

NukeWeaponsAdaptor - 基于我们的 Nuke 类,但是导出武器界面,现在我们肯定可以摧毁世界了。 。


Bridge 模式是你预先实现的,如果你知道你有两个正交的层次结构,它提供了一种将接口和实现解耦的方法 这样您就不会获得大量的类。 假设您有:

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

MemoryMappedWindowsFile
内存映射Linux文件
直接读取Windows文件
直接读取Linux文件

"Adapter makes things work after they're designed; Bridge makes them
work before they are. [GoF, p219]"

Effectively, the Adapter pattern is useful when you have existing code, be it third party, or in-house, but out of your control, or otherwise not changeable to quite meet the interface you need it to. For instance, we have a SuperWeaponsArray which can control a fine array of doomsday devices.

public class SuperWeaponsArray {
  /*...*/

  public void destroyWorld() {
    for (Weapon w : armedWeapons) {
      w.fire();
    }
  }
}

Great. Except we realize we have a nuclear device in our arsenal that vastly predates the conversion to the Weapon interface. But we'd really like it to work here... so what do we do... wedge it in!

NukeWeaponsAdaptor - based off of our Nuke class, but exporting the Weapon interface. Sweet, now we can surely destroy the world. It seems like bit of a kludge, but it makes things work.


The Bridge pattern is something you implement up front - if you know you have two orthogonal hierarchies, it provides a way to decouple the interface and the implementation in such a way that you don't get an insane number of classes. Let's say you have:

MemoryMappedFile and DirectReadFile types of file objects. Let's say you want to be able to read files from various sources (Maybe Linux vs. Windows implementations, etc.). Bridge helps you avoid winding up with:

MemoryMappedWindowsFile
MemoryMappedLinuxFile
DirectReadWindowsFile
DirectReadLinuxFile

池木 2024-08-11 22:57:26

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

适配器模式更多的是让你的适配器现有代码可用于较新的系统或界面。

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

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

桥接模式将允许您可能有算法或系统的替代实现。

虽然不是经典的桥接模式示例,但想象一下,如果您有一些数据存储的实现:一个在空间上高效,另一个在原始性能上高效......并且您有一个在应用程序或框架中提供这两种实现的业务案例。

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

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

The Adapter pattern is more about getting your existing code to work with a newer system or interface.

If you have a set of company-standard web service APIs that you'd like to offer to another application's existing extensibility interface, you might consider writing a set of adapters to do this. Note that there's a grey area and this is more about how you technically define the pattern, since other patterns like the facade are similar.

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

The Bridge pattern is going to allow you to possibly have alternative implementations of an algorithm or system.

Though not a classic Bridge pattern example, imagine if you had a few implementations of a data store: one is efficient in space, the other is efficient in raw performance... and you have a business case for offering both in your app or framework.

In terms of your question, "where I can use which pattern," the answer is, wherever it makes sense for your project! Perhaps consider offering a clarification edit to guide the discussion on where you believe you need to use one or the other.

峩卟喜欢 2024-08-11 22:57:26

适配器:

  1. 它是一种结构模式,
  2. 对于使用两个不兼容的接口非常有用

示例:

正方形和矩形是两种不同的形状并获取面积( )其中每一个都需要不同的方法。但 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);
    }
}

桥:

  1. 它是一种结构模式
  2. ,它将抽象与其实现解耦,以便两者都可以独立变化。

正如所解释的,该模式中有四个组件四种设计模式书(页数:174)

抽象:定义抽象的接口

RefinedAbstraction:扩展Abstraction定义的接口

Implementor:定义实现类的接口

ConcreteImplementor:实现Implementor接口并定义其具体实现。

请参阅下面的 SE 帖子中的代码:

何时使用桥接模式以及它与适配器模式有何不同?

Adapter:

  1. It is a structural pattern
  2. It is useful to work with two incompatible interfaces

Example:

Square and Rectangle are two different shapes and getting area() of each of them requires different methods. But still Square work on Rectangle interface with conversion of some of the properties.

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);
    }
}

Bridge:

  1. It is structural pattern
  2. it decouples an abstraction from its implementation so that both can vary independently

You have four components in this pattern as explained Gang of Four Design patterns book ( page: 174 )

Abstraction: defines the abstraction's interface

RefinedAbstraction: extends the interface defined by Abstraction

Implementor: defines the interface for implementation classes

ConcreteImplementor: implements the Implementor interface and defines its concrete implementation.

Refer to code in below SE post:

When to use the Bridge pattern and how is it different from the Adapter pattern?

七分※倦醒 2024-08-11 22:57:26

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

适配器与桥接器

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

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

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

In the top answer, @James quotes a sentence from the GoF, page 219. I think it's worthwhile reproducing the full explanation here.

Adapter versus Bridge

The Adapter and Bridge patterns have some common attributes. Both promote flexibility by providing a level of indirection to another object. Both involve
forwarding requests to this object from an interface other than its own.

The key difference between these patterns lies in their intents. Adapter focuses on
resolving incompatibilities between two existing interfaces. It doesn't focus on how
those interfaces are implemented, nor does it consider how they might evolve independently. It's a way of making two independently designed classes work together
without reimplementing one or the other. Bridge, on the other hand, bridges an abstraction and its (potentially numerous) implementations. It provides a stable interface
to clients even as it lets you vary the classes that implement it. It also accommodates
new implementations as the system evolves.

As a result of these differences, Adapter and Bridge are often used at different points
in the software lifecycle. An adapter often becomes necessary when you discover that
two incompatible classes should work together, generally to avoid replicating code. The
coupling is unforeseen. In contrast, the user of a bridge understands up-front that an
abstraction must have several implementations, and both may evolve independently.
The Adapter pattern makes things work after they're designed; Bridge makes them
work before they are. That doesn't mean Adapter is somehow inferior to Bridge; each
pattern merely addresses a different problem.

ζ澈沫 2024-08-11 22:57:26

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

This post has been around for quite a while. However, it is important to understand that a facade is somewhat similar to an adapter but it's not quite the same thing. An adapter "adapts" an existing class to a usually non-compatible client class. Let's say that you have an old workflow system that your application is using as a client. Your company could possibly replace the workflow system with a new "incompatible" one (in terms of interfaces). In most cases, you could use the adapter pattern and write code that actually calls the new workflow engine's interfaces. A bridge is generally used in a different way. If you actually have a system that needs to work with different file systems (i.e. local disk, NFS, etc.) you could use the bridge pattern and create one abstraction layer to work with all your file systems. This would basically be a simple use case for the bridge pattern. The Facade and the adapter do share some properties but facades are usually used to simplify an existing interface/class. In the early days of EJBs there were no local calls for EJBs. Developers always obtained the stub, narrowed it down and called it "pseudo-remotely". This often times caused performance problems (esp. when really called over the wire). Experienced developers would use the facade pattern to provide a very coarse-grained interface to the client. This facade would then in turn do multiple calls to different more fine-grained methods. All in all, this greatly reduced the number of method calls required and increased performance.

反差帅 2024-08-11 22:57:26

根据另一个 stackoverflow 答案这里,对我来说看起来更短、更清晰的答案:

  • 适配器当您有一个抽象接口并且您想要
    将该接口映射到具有类似功能的另一个对象
    角色,但界面不同。

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

Looks like shorter and clear answer to me according to another stackoverflow answer here:

  • Adapter is used when you have an abstract interface, and you want to
    map that interface to another object which has similar functional
    role, but a different interface.

  • Bridge is very similar to Adapter, but we call it Bridge when you
    define both the abstract interface and the underlying implementation.
    I.e. you're not adapting to some legacy or third-party code, you're
    the designer of all the code but you need to be able to swap out
    different implementations.

表情可笑 2024-08-11 22:57:26

Bridge是改进的Adapter。桥接器包括适配器并增加了额外的灵活性。
以下是 Ravindra 答案中的元素如何在模式之间映射:

      Adapter  |    Bridge
    -----------|---------------
    Target     | Abstraction
    -----------|---------------
               | RefinedAbstraction
               |
               |   This element is Bridge specific. If there is a group of 
               |   implementations that share the same logic, the logic can be placed here.
               |   For example, all cars split into two large groups: manual and auto. 
               |   So, there will be two RefinedAbstraction classes.
    -----------|--------------- 
    Adapter    | Implementor
    -----------|---------------
    Adaptee    | ConcreteImplementor

Bridge is improved Adapter. Bridge includes adapter and adds additional flexibility to it.
Here is how elements from Ravindra's answer map between patterns:

      Adapter  |    Bridge
    -----------|---------------
    Target     | Abstraction
    -----------|---------------
               | RefinedAbstraction
               |
               |   This element is Bridge specific. If there is a group of 
               |   implementations that share the same logic, the logic can be placed here.
               |   For example, all cars split into two large groups: manual and auto. 
               |   So, there will be two RefinedAbstraction classes.
    -----------|--------------- 
    Adapter    | Implementor
    -----------|---------------
    Adaptee    | ConcreteImplementor
烟柳画桥 2024-08-11 22:57:26

我认为这很简单。

该适配器旨在允许第三方应用程序与您的应用程序配合使用。
相反,这样您的应用程序就可以与第三方应用程序一起工作。

使用桥接模式,它应该连接两个或多个应用程序而无需实现适配器。

事实上,桥是两个应用程序进行交互的接口。作为桥接的示例,这些是 PHP 中的 PSR 接口。

示例:

OtherApp

<?php

interface IRequestDataOtherApp {};
 
interface IResponseDataOtherApp {};
 
class ResponseDataOtherApp implements IResponseDataOtherApp   {

}; 
 
class OtherApp {
    public static function request(IRequestDataOtherApp $requestData):IResponseOtherApp
    {
        // code
        return new ResponseDataOtherApp ();
    }
}

MyApp

<?php 

interface IResponseDataMyApp {};

interface IReqestDataMyApp {};

class ReqestDataMyApp implements IReqestDataMyApp {};

class Adapter {
   
    public static function convertResponseData(IResponseDataOtherApp $response):IResponseDataMyApp 
    {
      
    }
    public static function convertRequestData(IReqestDataMyApp $request):IRequestOtherApp
    {
      
    }
};
$unformattedResponse=OtherApp::request(Adapter::convertRequestData(new ReqestDataMyApp ()));
$myResponse=ResponseAdapter::convertResponseData($unformattedResponse);
//...

在前面的示例中,我们为每个请求和每个响应实现了 2 个适配器。
如果我们重写示例并尝试实现桥接器。

<?php
    interface IBridgeResponse {};

OtherApp

<?php
interface IRequestDataOtherApp {};
interface IResponseDataOtherApp {};
 
class ResponseDataOtherApp  implements IBridgeResponse, IResponseDataOtherApp   {

}; 
 
class OtherApp {
    public static function request(IRequestDataOtherApp $requestData):IResponseOtherApp
    {
        // code
        return new ResponseDataOtherApp  ();
    }
}

MyApp

<?php 

interface IResponseDataMyApp {};

interface IReqestDataMyApp {};

class ReqestDataMyApp implements IReqestDataMyApp {};

class Adapter {

    public static function convertResponseData(IResponseDataOtherApp $response):IResponseDataMyApp 
    {
      
    }

    public static function convertRequestData(IReqestDataMyApp $request):IRequestOtherApp
   {
      
   }
};

$response=OtherApp::request(Adapter::convertRequestData(new ReqestDataMyApp ()));

if($response instanceof IBridgeResponse){
  /** 
The component has implemented IBridgeResponse interface,
thanks to which our application can interact with it.
This is the bridge.

Our application does not have to create an additional adapter
 (if our application can work with IBridgeResponse).
*/
}
//...

在六边形架构中,如果您从一开始就编写应用程序并准备好接受正在使用的另一个应用程序的规则,则端口(接口、合约)可以充当“桥梁”。
否则,您将不得不编写“适配器”。

I think it's simple.

The adapter is designed to allow a third party application to work with your application.
Conversely, so that your application can work with third party applications.

Using the bridge pattern, it is supposed to connect two or more applications without implementing an adapter.

In fact, a bridge is an interface through which two applications will interact. As an example of bridging, these are PSR interfaces in PHP.

Example:

OtherApp

<?php

interface IRequestDataOtherApp {};
 
interface IResponseDataOtherApp {};
 
class ResponseDataOtherApp implements IResponseDataOtherApp   {

}; 
 
class OtherApp {
    public static function request(IRequestDataOtherApp $requestData):IResponseOtherApp
    {
        // code
        return new ResponseDataOtherApp ();
    }
}

MyApp

<?php 

interface IResponseDataMyApp {};

interface IReqestDataMyApp {};

class ReqestDataMyApp implements IReqestDataMyApp {};

class Adapter {
   
    public static function convertResponseData(IResponseDataOtherApp $response):IResponseDataMyApp 
    {
      
    }
    public static function convertRequestData(IReqestDataMyApp $request):IRequestOtherApp
    {
      
    }
};
$unformattedResponse=OtherApp::request(Adapter::convertRequestData(new ReqestDataMyApp ()));
$myResponse=ResponseAdapter::convertResponseData($unformattedResponse);
//...

In the before example, we have implemented 2 adapters per request and per response.
If we rewrite example and try to implement the bridge.

<?php
    interface IBridgeResponse {};

OtherApp

<?php
interface IRequestDataOtherApp {};
interface IResponseDataOtherApp {};
 
class ResponseDataOtherApp  implements IBridgeResponse, IResponseDataOtherApp   {

}; 
 
class OtherApp {
    public static function request(IRequestDataOtherApp $requestData):IResponseOtherApp
    {
        // code
        return new ResponseDataOtherApp  ();
    }
}

MyApp

<?php 

interface IResponseDataMyApp {};

interface IReqestDataMyApp {};

class ReqestDataMyApp implements IReqestDataMyApp {};

class Adapter {

    public static function convertResponseData(IResponseDataOtherApp $response):IResponseDataMyApp 
    {
      
    }

    public static function convertRequestData(IReqestDataMyApp $request):IRequestOtherApp
   {
      
   }
};

$response=OtherApp::request(Adapter::convertRequestData(new ReqestDataMyApp ()));

if($response instanceof IBridgeResponse){
  /** 
The component has implemented IBridgeResponse interface,
thanks to which our application can interact with it.
This is the bridge.

Our application does not have to create an additional adapter
 (if our application can work with IBridgeResponse).
*/
}
//...

In hexagonal architecture, Ports (Interfaces, Contracts) can act as 'Bridges' if you write an application from the very beginning and are ready to accept the rules of another application being used.
Otherwise, you will have to write 'Adapters'.

望笑 2024-08-11 22:57:26

假设您有一个具有(通用/抽象)绘图功能的抽象 Shape 类和一个实现 Shape 的 Circle。桥接模式只是一种双向抽象方法,用于解耦实现(在 Circle 中绘制)和通用/抽象功能(在 Shape 类中绘制)。

它到底意味着什么?乍一看,这听起来像是您已经制作的东西(通过依赖倒置)。因此,不必担心拥有不那么僵化或更模块化的代码库。但这背后有更深层次的哲学。

根据我的理解,当我需要添加与当前系统密切相关的新类(如 RedCircle 或 GreenCircle )并且它们仅在单个功能上有所不同(如 color )时,可能会出现使用模式的需求。我将需要 Bridge 模式,特别是如果现有系统类( Circle 或 Shape )要经常更改,并且您不希望新添加的类受到这些更改的影响。这就是为什么通用绘图功能被抽象到一个新接口中,以便您可以独立于形状或圆形来更改绘图行为。

Suppose you've a abstract Shape class with a (generic/abstracted) drawing functionality and a Circle who implements the Shape. Bridge pattern simply is a two-way abstraction approach to decouple the implementation ( drawing in Circle ) and generic/abstracted functionality ( drawing in the Shape class ).

What does it really mean? At a first glance, it sounds like a something you already making ( by dependency inversion). So no worries about having a less-ridig or more modular code base. But it's a bit deeper philosophy behind it.

From my understanding, the need of usage pattern might emerge when I need to add new classes which are closely related with the current system ( like RedCircle or GreenCircle ) and which they differ by only a single functionality ( like color ). And I'm gonna need Bridge pattern particularly if the existing system classes ( Circle or Shape ) are to be frequently changed and you don't want newly added classes to be affected from those changes. So that's why the generic drawing functionality is abstracted away into a new interface so that you can alter the drawing behaviour independent from Shape or Circle.

咆哮 2024-08-11 22:57:26

有很多答案可以区分适配器和桥接器。
但当人们寻找代码示例时,我将给出一个将适配器设计模式制作成时间线故事的示例:

    //---------------------------------------External Vendor/Provider--------------------------------
   
            //Adaptee | RussianTankInterface is adaptee | adaptee lives in is own lala land and do not care about any other class or interface
            RussianTankInterface smerch9K58 = new RussianTank("The Russian Artillery bought by India in October 2015");
                smerch9K58.aboutMyself();
                smerch9K58.stuff();
                smerch9K58.rotate();
                smerch9K58.launch();
        
   
    //---------------------------------2016 : India manufactures Bharat52 ------------------------------ 
    
            //Client_1 :: IndianTank 
            EnemyAttacker bharat52Attacker = new IndianTank("Tank built in India delivered to Army in Jul 2016"); 
   
            // behaves normally -------------------------(1)
                bharat52Attacker.aboutMe();
                bharat52Attacker.load();
                bharat52Attacker.revolve();
                bharat52Attacker.fireArtillery();
                
    //---------------------------------2019 : India mnufactures Pinaka, and thought about fusion with Russian technology - so adaption required ------------------------------ 
                  
            //Client_2 :: IndianTank 
            EnemyAttacker pinakaAttacker = new IndianTank("Tank built in India in 1998 got upgraded_v1 in 9 Sep 2019"); 
            
            
            
#####----Bilateral-Coalition happens----## 
#####       India  : I want a fusion artillery technology with 
#####                       1) Indian materials and brain-power but
#####                       2) Russian machine-parts-movement technology 
#####       Russia : Give me your Interface - at max we can help by providing an Adapter 
    
    //---------------------------------------External Vendor/Provider-----------------------------------
    
            //Adapter :: RussianTechnologyAdapter | Russia gets EnemyAttacker interface only from India & creates RussianTechnologyAdapter 
            RussianTechnologyAdapter russianTechnologyAdapter = new RussianTechnologyAdapter(smerch9K58);
           
           
            //Target | EnemyAttacker was initially ClientInterface but later becomes the Target as story evolves | <- client owns this Interface
            EnemyAttacker dhanushAttacker = russianTechnologyAdapter;
            
#####----Russia keeps her Word----## 
#####       Russia to India : Here you go! Take Dhanush, a wrapper over our encapsulated adapter, and plug-in anything conforming to your EnemyAttacker.
#####       India : Thanks a lot!

    //--------------------------------- 2020 : India returns back happily with dhanushAttacker--------------------------------------- 
            
            //Client_2 - adapted behavior -------------------------(2)
                dhanushAttacker.setNavigationCapability(pinakaAttacker.getCuttingEdgeNavigableTargets());
                dhanushAttacker.aboutMe(); //calls RussianInstance -> aboutMyself()
                dhanushAttacker.load();    //calls RussianInstance -> stuff()
                dhanushAttacker.revolve(); //calls RussianInstance -> rotate()
                dhanushAttacker.fireArtillery();  //calls RussianInstance -> launch()
                       
          

仔细注意:

  • (1) 和 (1) 中的相同 API (2) 表现不同
  • 印度可以将其大脑推向俄罗斯的wireFrame,例如 dhanushAttacker.setNavigationCapability(pinakaAttacker.get(..))

值得注意的点

客户端拥有:

-  Invoker /Use(uses Adapter later point)/Client
-  ClientInterface (a.k.a Target )

稍后共享:

- ClientInterface  ( becomes Target after sharing)

接收方拥有:

- Adapter (later shared directly or as a wrapper )  
- Adaptee

     

希望有人也为 Bridge 提供内联:)

There are plenty of answers To distinguish between Adapter and Bridge.
But as ppl are looking for code examples, I would give one example for Adapter Design Pattern crafted into a timeline story :

    //---------------------------------------External Vendor/Provider--------------------------------
   
            //Adaptee | RussianTankInterface is adaptee | adaptee lives in is own lala land and do not care about any other class or interface
            RussianTankInterface smerch9K58 = new RussianTank("The Russian Artillery bought by India in October 2015");
                smerch9K58.aboutMyself();
                smerch9K58.stuff();
                smerch9K58.rotate();
                smerch9K58.launch();
        
   
    //---------------------------------2016 : India manufactures Bharat52 ------------------------------ 
    
            //Client_1 :: IndianTank 
            EnemyAttacker bharat52Attacker = new IndianTank("Tank built in India delivered to Army in Jul 2016"); 
   
            // behaves normally -------------------------(1)
                bharat52Attacker.aboutMe();
                bharat52Attacker.load();
                bharat52Attacker.revolve();
                bharat52Attacker.fireArtillery();
                
    //---------------------------------2019 : India mnufactures Pinaka, and thought about fusion with Russian technology - so adaption required ------------------------------ 
                  
            //Client_2 :: IndianTank 
            EnemyAttacker pinakaAttacker = new IndianTank("Tank built in India in 1998 got upgraded_v1 in 9 Sep 2019"); 
            
            
            
#####----Bilateral-Coalition happens----## 
#####       India  : I want a fusion artillery technology with 
#####                       1) Indian materials and brain-power but
#####                       2) Russian machine-parts-movement technology 
#####       Russia : Give me your Interface - at max we can help by providing an Adapter 
    
    //---------------------------------------External Vendor/Provider-----------------------------------
    
            //Adapter :: RussianTechnologyAdapter | Russia gets EnemyAttacker interface only from India & creates RussianTechnologyAdapter 
            RussianTechnologyAdapter russianTechnologyAdapter = new RussianTechnologyAdapter(smerch9K58);
           
           
            //Target | EnemyAttacker was initially ClientInterface but later becomes the Target as story evolves | <- client owns this Interface
            EnemyAttacker dhanushAttacker = russianTechnologyAdapter;
            
#####----Russia keeps her Word----## 
#####       Russia to India : Here you go! Take Dhanush, a wrapper over our encapsulated adapter, and plug-in anything conforming to your EnemyAttacker.
#####       India : Thanks a lot!

    //--------------------------------- 2020 : India returns back happily with dhanushAttacker--------------------------------------- 
            
            //Client_2 - adapted behavior -------------------------(2)
                dhanushAttacker.setNavigationCapability(pinakaAttacker.getCuttingEdgeNavigableTargets());
                dhanushAttacker.aboutMe(); //calls RussianInstance -> aboutMyself()
                dhanushAttacker.load();    //calls RussianInstance -> stuff()
                dhanushAttacker.revolve(); //calls RussianInstance -> rotate()
                dhanushAttacker.fireArtillery();  //calls RussianInstance -> launch()
                       
          

Carefully notice :

  • Same API in (1) & (2) behaves differently
  • India can push its brain into wireFrame of Russia e.g dhanushAttacker.setNavigationCapability(pinakaAttacker.get(..))

Noteworthy points

Client side owns:

-  Invoker /Use(uses Adapter later point)/Client
-  ClientInterface (a.k.a Target )

Shared later:

- ClientInterface  ( becomes Target after sharing)

Receiver side owns :

- Adapter (later shared directly or as a wrapper )  
- Adaptee

     

Hoping someone gives an inline for Bridge too :)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文