DESIGN DESIGN
  • 架构
  • 设计模式
  • 重构
  • UML
GitHub (opens new window)
  • 架构
  • 设计模式
  • 重构
  • UML
GitHub (opens new window)
  • 架构

  • 设计模式

    • 设计模式概述
    • 设计模式之简单工厂模式
    • 设计模式之工厂方法模式
    • 设计模式之抽象工厂模式
    • 设计模式之建造者模式
    • 设计模式之原型模式
    • 设计模式之单例模式
    • 设计模式之适配器模式
    • 设计模式之桥接模式
      • 意图
      • 适用场景
      • 结构
        • 结构说明
        • 结构代码范式
      • 伪代码
      • 案例
      • 与其他模式的关系
      • 参考资料
    • 设计模式之组合模式
    • 设计模式之装饰模式
    • 设计模式之外观模式
    • 设计模式之享元模式
    • 设计模式之代理模式
    • 设计模式之模板方法模式
    • 设计模式之命令模式
    • 设计模式之迭代器模式
    • 设计模式之观察者模式
    • 设计模式之解释器模式
    • 设计模式之中介者模式
    • 设计模式之职责链模式
    • 设计模式之备忘录模式
    • 设计模式之策略模式
    • 设计模式之访问者模式
    • 设计模式之状态模式
    • 面向对象原则
  • 重构

  • DDD

  • UML

  • 设计
  • 设计模式
dunwu
2015-01-16
目录

设计模式之桥接模式

# 设计模式之桥接模式

# 意图

桥接模式 (Bridge) 是一种结构型设计模式, 可将抽象部分与实现部分分离,使它们都可以独立的变化。

如果一个系统需要在构件的抽象化角色和具体化角色之间增加更多的灵活性,避免在两个层次之间建立静态的联系。抽象化角色和具体化角色都应该可以被子类扩展。在这种情况下,桥接模式可以灵活地组合不同的抽象化角色和具体化角色,并独立化地扩展。

设计要求实现化角色的任何改变不应当影响客户端,或者说实现化角色的改变对客户端是完全透明的。

# 适用场景

  • 如果你想要拆分或重组一个具有多重功能的庞杂类(例如能与多个数据库服务器进行交互的类),可以使用桥接模式。
  • 如果你希望在几个独立维度上扩展一个类, 可使用该模式。
  • 如果你需要在运行时切换不同实现方法, 可使用桥接模式。

# 结构

img

# 结构说明

  1. 抽象部分 (Abstraction) 提供高层控制逻辑, 依赖于完成底层实际工作的实现对象。
  2. 实现部分 (Implementation) 为所有具体实现声明通用接口。 抽象部分仅能通过在这里声明的方法与实现对象交互。
    • 抽象部分可以列出和实现部分一样的方法, 但是抽象部分通常声明一些复杂行为, 这些行为依赖于多种由实现部分声明的原语操作。
  3. 具体实现 (Concrete Implementations) 中包括特定于平台的代码。
  4. 精确抽象 (Refined Abstraction) 提供控制逻辑的变体。 与其父类一样, 它们通过通用实现接口与不同的实现进行交互。
  5. 通常情况下, 客户端 (Client) 仅关心如何与抽象部分合作。 但是, 客户端需要将抽象对象与一个实现对象连接起来。

# 结构代码范式

【Implementor】定义实现接口。

interface Implementor {
    // 实现抽象部分需要的某些具体功能
    public void operationImpl();
}

【Abstraction】定义抽象接口。

abstract class Abstraction {
    // 持有一个 Implementor 对象,形成聚合关系
    protected Implementor implementor;

    public Abstraction(Implementor implementor) {
        this.implementor = implementor;
    }

    // 可能需要转调实现部分的具体实现
    public void operation() {
        implementor.operationImpl();
    }
}

【ConcreteImplementor】实现 Implementor 中定义的接口。

class ConcreteImplementorA implements Implementor {
    @Override
    public void operationImpl() {
        // 真正的实现
        System.out.println("具体实现A");
    }
}

class ConcreteImplementorB implements Implementor {
    @Override
    public void operationImpl() {
        // 真正的实现
        System.out.println("具体实现B");
    }
}

【RefinedAbstraction】扩展 Abstraction 类。

class RefinedAbstraction extends Abstraction {

    public RefinedAbstraction(Implementor implementor) {
        super(implementor);
    }

    public void otherOperation() {
        // 实现一定的功能,可能会使用具体实现部分的实现方法,
        // 但是本方法更大的可能是使用 Abstraction 中定义的方法,
        // 通过组合使用 Abstraction 中定义的方法来完成更多的功能。
    }
}

【客户端】

public class BridgePattern {
    public static void main(String[] args) {
        Implementor implementor = new ConcreteImplementorA();
        RefinedAbstraction abstraction = new RefinedAbstraction(implementor);
        abstraction.operation();
        abstraction.otherOperation();
    }
}

【输出】

具体实现A
其他操作

# 伪代码

img

遥控器基类声明了一个指向设备对象的引用成员变量。 所有遥控器通过通用设备接口与设备进行交互, 使得同一个遥控器可以支持不同类型的设备。

你可以开发独立于设备类的遥控器类, 只需新建一个遥控器子类即可。 例如, 基础遥控器可能只有两个按钮, 但你可在其基础上扩展新功能, 比如额外的一节电池或一块触摸屏。

客户端代码通过遥控器构造函数将特定种类的遥控器与设备对象连接起来。

// “抽象部分”定义了两个类层次结构中“控制”部分的接口。它管理着一个指向“实
// 现部分”层次结构中对象的引用,并会将所有真实工作委派给该对象。
class RemoteControl is
    protected field device: Device
    constructor RemoteControl(device: Device) is
        this.device = device
    method togglePower() is
        if (device.isEnabled()) then
            device.disable()
        else
            device.enable()
    method volumeDown() is
        device.setVolume(device.getVolume() - 10)
    method volumeUp() is
        device.setVolume(device.getVolume() + 10)
    method channelDown() is
        device.setChannel(device.getChannel() - 1)
    method channelUp() is
        device.setChannel(device.getChannel() + 1)


// 你可以独立于设备类的方式从抽象层中扩展类。
class AdvancedRemoteControl extends RemoteControl is
    method mute() is
        device.setVolume(0)


// “实现部分”接口声明了在所有具体实现类中通用的方法。它不需要与抽象接口相
// 匹配。实际上,这两个接口可以完全不一样。通常实现接口只提供原语操作,而
// 抽象接口则会基于这些操作定义较高层次的操作。
interface Device is
    method isEnabled()
    method enable()
    method disable()
    method getVolume()
    method setVolume(percent)
    method getChannel()
    method setChannel(channel)


// 所有设备都遵循相同的接口。
class Tv implements Device is
    // ...

class Radio implements Device is
    // ...


// 客户端代码中的某个位置。
tv = new Tv()
remote = new RemoteControl(tv)
remote.togglePower()

radio = new Radio()
remote = new AdvancedRemoteControl(radio)

# 案例

使用示例: 桥接模式在处理跨平台应用、 支持多种类型的数据库服务器或与多个特定种类 (例如云平台和社交网络等) 的 API 供应商协作时会特别有用。

识别方法: 桥接可以通过一些控制实体及其所依赖的多个不同平台之间的明确区别来进行识别。

Java 中桥接模式应用最经典的代表无疑是日志组件 slf4j 的桥接 jar 包。

假如,你正在开发应用程序所调用的组件当中已经使用了 common-logging,这时你需要 jcl-over-slf4j.jar 把日志信息输出重定向到 slf4j-api,slf4j-api 再去调用 slf4j 实际依赖的日志组件。这个过程称为桥接。下图是官方的 slf4j 桥接策略图:

img

# 与其他模式的关系

  • 桥接模式 (opens new window)通常会于开发前期进行设计, 使你能够将程序的各个部分独立开来以便开发。 另一方面, 适配器模式 (opens new window)通常在已有程序中使用, 让相互不兼容的类能很好地合作。
  • 桥接 (opens new window)、 状态模式 (opens new window)和策略模式 (opens new window) (在某种程度上包括适配器 (opens new window)) 模式的接口非常相似。 实际上, 它们都基于组合模式 (opens new window)——即将工作委派给其他对象, 不过也各自解决了不同的问题。 模式并不只是以特定方式组织代码的配方, 你还可以使用它们来和其他开发者讨论模式所解决的问题。
  • 你可以将抽象工厂模式 (opens new window)和桥接 (opens new window)搭配使用。 如果由桥接定义的抽象只能与特定实现合作, 这一模式搭配就非常有用。 在这种情况下, 抽象工厂可以对这些关系进行封装, 并且对客户端代码隐藏其复杂性。
  • 你可以结合使用生成器模式 (opens new window)和桥接模式 (opens new window): 主管类负责抽象工作, 各种不同的生成器负责实现工作。

# 参考资料

  • 《Head First 设计模式》 (opens new window)
  • 《大话设计模式》 (opens new window)
  • 设计模式教程 (opens new window)
📝 帮助改善此页面! (opens new window)
#设计#设计模式
上次更新: 2024/01/27, 23:24:21
设计模式之适配器模式
设计模式之组合模式

← 设计模式之适配器模式 设计模式之组合模式→

最近更新
01
设计
04-27
02
微服务简介
04-15
03
如何设计系统
11-08
更多文章>
Theme by Vdoing | Copyright © 2019-2024 钝悟(dunwu) | CC-BY-SA-4.0
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式
×