设计模式——桥接模式

这篇具有很好参考价值的文章主要介绍了设计模式——桥接模式。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

引用

我们大家都熟悉,顾名思义就是用来将河的两岸联系起来的。而此处的桥是用来将两个独立的结构联系起来,而这两个被联系起来的结构可以独立的变化,所有其他的理解只要建立在这个层面上就会比较容易。

基本介绍

  • 桥接模式(Bridge)是指将实现与抽象放在两个不同的类层次中,是两个层次可以独立改变。
  • 该模式基于类的最小设计原则(扩展功能时尽量少的增加类),通过使用封装、聚合、继承等行为让不同的类承担不同的职责。
  • 主要特点是把抽象和行为实现分离开来,从而可以保持各部分的独立性以及对他们的功能扩展。
  • 桥梁模式的用意是将抽象化与实现化脱耦,使得二者可以独立地变化。

原理类图

设计模式——桥接模式,设计模式,设计模式,桥接模式

 桥接(Bridge)模式包含以下主要角色:

  • client:桥接模式的调用者

  • Implementor:实现化角色,它是接口或者抽象类,定义角色必需的行为和属性;这个接口不一定要与Abstraction的接口完全一致,事实上这两个接口可以完全不同,一般而言,Implementor接口仅提供基本操作,而Abstraction定义的接口可能会做更多更复杂的操作。Implementor接口对这些基本操作进行了声明,而具体实现交给其子类。通过关联关系,Abstraction不仅拥有自己的方法,还可以调用Implementor中定义的方法,使用关联关系来替代继承关系;
  • ConcreteImplementor:具体实现化角色,实现接口或抽象类定义的方法或属性。在不同的ConcreteImplementor中提供基本操作的不同实现,在程序运行时,ConcreteImplementor对象将替换其父类对象,提供给抽象类具体的业务操作方法;
  • Abstraction:抽象化角色,定义出该角色的行为,同时保存一个对实现化角色的引用;它一般是抽象类而不是接口,其中定义了一个Implementor(实现类接口)类型的对象并可以维护该对象,它与Implementor之间具有关联关系,它既可以包含抽象业务方法,也可以包含具体业务方法;
  • RefinedAbstraction:扩充抽象类角色,引用实现化角色对抽象化角色进行扩充。通常情况下,它不再是抽象类而是具体类,它实现了在Abstraction中声明的抽象业务方法,在RefinedAbstraction中可以调用在Implementor中定义的业务方法;

从UML图看,这里的抽象类和接口是聚合关系,就是调用和被调用的关系;RefinedAbstraction的父类聚合了接口,RefinedAbstraction调用接口的具体实现

优缺点

通过上面的讲解,我们能很好的感觉到桥接模式遵循了里氏替换原则和依赖倒置原则,最终实现了开闭原则,对修改关闭,对扩展开放。这里将桥接模式的优缺点总结如下。  

优点:
  • 分离抽象接口及其实现部分。桥接模式使用“对象间的关联关系”解耦了抽象和实现之间固有的绑定关系,使得抽象和实现可以沿着各自的维度来变化。所谓抽象和实现沿着各自维度的变化,也就是说抽象和实现不再在同一个继承层次结构中,而是“子类化”它们,使它们各自都具有自己的子类,以便任何组合子类,从而获得多维度组合对象。
  • 在很多情况下,桥接模式可以取代多层继承方案,多层继承方案违背了“单一职责原则”,复用性较差,且类的个数非常多,桥接模式是比多层继承方案更好的解决方法,它极大减少了子类的个数。
  • 桥接模式提高了系统的可扩展性,在两个变化维度中任意扩展一个维度,都不需要修改原有系统,符合“开闭原则”。
缺点:
  • 桥接模式的使用会增加系统的理解与设计难度,由于关联关系建立在抽象层,要求开发者一开始就针对抽象层进行设计与编程。
  • 桥接模式要求正确识别出系统中两个独立变化的维度,因此其使用范围具有一定的局限性,如何正确识别两个独立维度也需要一定的经验积累。

模式的实现

桥接模式的代码如下:

package bridge;
public class BridgeTest {
    public static void main(String[] args) {
        Implementor imple = new ConcreteImplementorA();
        Abstraction abs = new RefinedAbstraction(imple);
        abs.Operation();
    }
}
//实现化角色
interface Implementor {
    public void OperationImpl();
}
//具体实现化角色
class ConcreteImplementorA implements Implementor {
    public void OperationImpl() {
        System.out.println("具体实现化(Concrete Implementor)角色被访问");
    }
}
//抽象化角色
abstract class Abstraction {
    protected Implementor imple;
    protected Abstraction(Implementor imple) {
        this.imple = imple;
    }
    public abstract void Operation();
}
//扩展抽象化角色
class RefinedAbstraction extends Abstraction {
    protected RefinedAbstraction(Implementor imple) {
        super(imple);
    }
    public void Operation() {
        System.out.println("扩展抽象化(Refined Abstraction)角色被访问");
        imple.OperationImpl();
    }
}
​

程序的运行结果如下:

扩展抽象化(Refined Abstraction)角色被访问
具体实现化(Concrete Implementor)角色被访问

案例场景模拟

假设设计一个日志系统,这个系统可以记录多种日志类型,如交易日志,数据库日志,用户操作日志等,同时,这个系统还支持多种日志的表现形式。如xml文件,文本文件,数据库库数据,E-mail等。

    抽象:日志的种类。

    实现:日志的表现方式。

实现代码如下:

Log源代码

public abstract class Log{
    protected LogSave logSave;
    public Log(LogSave logSave){
        this.logSave=logSave;
    }
    public abstract void writeToLog();
}

LogSave源代码

public abstract class LogSave{
    public abstract void write();
}

下面是三个Log的子类

TradLog源代码

public class TradLog extends Log{
    public TradLog(LogSave logSave){
        super(logSave);
    }
   
   @Override
   public void writeToLog(){
       System.out.println("写入TradLog数据");
       this.logSave.write();
   }
}

DbLog源代码

public class DbLog extends Log{
    public DbLog(LogSave logSave){
        super(logSave);
    }
   
   @Override
   public void writeToLog(){
       System.out.println("写入DbLog数据");
       this.logSave.write();
   }
}

UserLog源代码

public class UserLog extends Log{
    public UserLog(LogSave logSave){
        super(logSave);
    }
   
   @Override
   public void writeToLog(){
       System.out.println("写入UserLog数据");
       this.logSave.write();
   }
}

下面是LogSave的三个实现类

XmlImpl源代码

public class XmlImpl extends LogSave{
    @Override
    public void write(){
        System.out.println("使用xml方式存储");
    }
}

TextImpl源代码

public class TextImpl extends LogSave{
    @Override
    public void write(){
        System.out.println("使用文本方式存储");
    }
}

 EmailImpl源代码

public class EmailImpl extends LogSave{
    @Override
    public void write(){
        System.out.println("使用发邮件的方式存储");
    }
}

实现不能和抽象发生耦合,而只能由抽象和实现发生耦合。

下面是启动类展示最终结果:

Client源代码

public class Client{
    public static void main(String[] args){
        Log log=new UserLog(new XmlImpl());
        log.writeToLog();
        
        Log log2=new DbLog(new EmailImpl());
        log2.writeToLog();
    }
}

运行结果如下:

写入UserLog数据

使用xml方式存储

写入DbLog数据

使用发邮件的方式存储

应用场景

  • 如果一个系统需要在构件的抽象化角色和具体化角色之间增加更多的灵活性,避免在两个层次之间建立静态的继承联系,通过桥接模式可以使它们在抽象层建立一个关联关系。
  • 对于那些不希望使用继承或因为多层次继承导致系统类的个数急剧增加的系统,桥接模式尤为适用。
  • 一个类存在两个独立变化的维度,且这两个维度都需要进行扩展。
  • 常用的场景:
    • JDBC驱动程序
    • 日志框架
    • 银行转账系统
      • 转账分类:网上转账、柜台转账、ATM转账
      • 用户类型:普通用户、银卡用户、金卡用户
    • 消息管理
      • 消息类型:即时消息、延时消息
      • 消息分类:手机短信、邮件信息、QQ消息

桥接模式模式的扩展

在软件开发中,有时桥接(Bridge)模式可与适配器模式联合使用。当桥接(Bridge)模式的实现化角色的接口与现有类的接口不一致时,可以在二者中间定义一个适配器将二者连接起来,其具体结构图如图桥接模式与适配器模式联用的结构图所示。

设计模式——桥接模式,设计模式,设计模式,桥接模式文章来源地址https://www.toymoban.com/news/detail-657644.html

小结

  • 对于系统的高层来说,只需要知道抽象部分和实现部分的接口就够了,其他部分由具体业务来完成
  • 桥接模式代替多层继承方案,可以减少子类的个数,降低系统的管理和维护成本
  • 桥接模式要求正确识别出系统中的两个独立变化维度,因此其使用范围有一定的局限性,适用于一定的应用场景

到了这里,关于设计模式——桥接模式的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 设计模式详解-桥接模式

    类型:结构型模式 实现原理:将抽象类和实现类分离,使其独立,然后使用接口再将二者连接起来。 意图:将抽象部分与实现部分分离,使它们都可以独立的变化。 主要解决:类变化频繁时用继承可能会出现的类爆炸问题。 如何解决:减少类的耦合关系,让类独立变化。

    2024年02月12日
    浏览(45)
  • 设计模式-桥接模式

    适配器模式 类似,以后也会遇到意思接近一样的设计模式。在开发中一般多个模式混用,且根据不同的场景进行搭配,桥接模式也是 结构型模式 将抽象的部分和实现的部分分离,使它们都可以独立的变化。通俗来说,就是通过组合来 桥接 其它的 行为或维度 与适配器模式业

    2024年02月11日
    浏览(46)
  • 设计模式之~桥接模式

    桥接模式:         将抽象部分与它的实现部分分离,使他们都可以独立地变化。这种类型的设计模式属于结构型模式,它通过提供抽象化和实现化之间的桥接结构,来实现二者的解耦。         什么叫抽象与它的实现分离,这并不是说,让抽象类与其派生类分离,因

    2024年02月07日
    浏览(40)
  • 【前端设计模式】之桥接模式

    设计模式是在软件开发中经过验证的解决问题的方法。它们是从经验中总结出来的,可以帮助我们更好地组织和管理代码,提高代码的可维护性、可扩展性和可重用性。无论是前端还是后端开发,设计模式都扮演着重要的角色。在本专栏中,我们将探索一些常见的前端设计模

    2024年02月04日
    浏览(45)
  • Java设计模式-桥接模式

    桥接模式是将抽象部分与它的实现部分分离,使它们都可以独立地变化。 这个概念听着那是相当拗口了,其实通过例子解释后,就能很好的理解了。 下面先看一个例子,这个例子表现了手机与手机软件之间的关系 2.1HandsetSoft类 这个类是手机软件的抽象类 2.2HandSetGame类 这个是

    2024年02月16日
    浏览(42)
  • js设计模式:桥接模式

    可以将复杂的类进行一些拆分,让抽象和实现进行分离解耦,可以让每一个部分都可以单独维护 方便扩展和维护

    2024年02月22日
    浏览(36)
  • 设计模式-桥接模式(Bridge)

    桥接模式(Bridge Pattern)是一种结构型设计模式,用于将抽象部分和实现部分分离,使它们可以独立地变化。这种分离允许你将一个类的功能层次结构(抽象)与另一个类的实现层次结构(实现)分开,从而在不同层次上进行修改和扩展。在本篇博客中,我们将详细介绍桥接

    2024年02月09日
    浏览(55)
  • 【结构型设计模式】C#设计模式之桥接模式

    题目:设计一个桥接模式来实现图形和颜色之间的解耦。 解析: 桥接模式是一种结构型设计模式,它将抽象部分与实现部分分离,使它们可以独立变化。在这个例子中,抽象部分是图形(如圆形、正方形),实现部分是颜色(如红色、蓝色)。 我们可以使用桥接模式来解耦

    2024年02月13日
    浏览(43)
  • 结构型设计模式——桥接模式

    桥接模式(Bridge pattern): 使用桥接模式通过将实现和抽象放在两个不同的类层次中而使它们可以独立改变。 桥接模式 (Bridge) 是一种结构型设计模式, 可将 抽象 部分与 实现 部分 分离 ,使它们都可以独立的变化。如果一个系统需要在构件的抽象化角色和具体化角色之间增加更

    2024年02月07日
    浏览(49)
  • 【23种设计模式】桥接模式(七)

    【 桥接模式 】是【 结构型 】设计模式的第二个模式,也有叫【桥模式】的,英文名称: Bridge Pattern 。 大家第一次看到这个名称会想到什么呢?我第一次看到这个模式根据名称猜肯定是连接什么东西的。因为桥在我们现实生活中经常是连接着A地和B地,再往后来发展,桥引

    2024年02月10日
    浏览(41)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包