首页 > 其他分享 >设计模式 - 桥接模式

设计模式 - 桥接模式

时间:2022-10-23 18:57:53浏览次数:87  
标签:Implementor 桥接 db 模式 export 接口 设计模式 public

目录

实例

数据转换工具

Sunny软件公司欲开发一个数据转换工具,可以将数据库中的数据转换成多种文件格式,例如txtxmlpdf等格式,同时该工具需要支持多种不同的数据库

在这里插入图片描述

初始设计方案如上图所示,使用了一种多层继承结构,Data是抽象父类,每一种类型的文件类如XmlDataTxtData等作为其直接子类;每一种数据来源于不同的数据库,不同的数据类再提供一组在不同数据库的子类,不难看出,该方案存在以下问题:
(1) 采用了多层继承结构,导致系统中类的个数急剧增加
(2) 系统扩展麻烦,由于每一个具体类既包含数据格式信息,又包含数据库信息,增加每一个维度都需要增加大量的具体类


桥接模式

概念

  • 桥接模式(Bridge Pattern):将抽象部分与它的实现部分分离,使它们都可以独立地变化
  • 桥接模式通过组合的方式建立两个类之间的联系,而不是继承
  • 桥接模式是一种对象结构型模式
  • 桥接模式又称为柄体(Handle and Body)模式或接口(Interface)模式
  • 桥接模式结构图(来自刘伟老师技术博客)

在这里插入图片描述


角色定义

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

典型代码

  • Implementor
interface Implementor {
	public void operationImpl();
}
  • Abstraction
abstract class Abstraction {
	protected Implementor impl; //定义实现类接口对象
	
	public void setImpl(Implementor impl) {
		this.impl=impl;
	}
	
	public abstract void operation();  //声明抽象业务方法
}
  • RefinedAbstraction
class RefinedAbstraction extends Abstraction {
	public void operation() {
		//业务代码
		impl.operationImpl();  //调用实现类的方法
		//业务代码
	}
}

具体实现

  • DB.java
/**
 * @Description 抽象数据库:实现类接口
 */
public interface DB {
    /**
     * 获取数据
     */
    void export();
}
  • MysqlDB.java
/**
 * @Description Mysql数据库实现类:具体实现类
 */
public class MysqlDB implements DB {
    @Override
    public void export() {
        System.out.print("获取Mysql数据 ");
    }
}
  • OracleDB.java
/**
 * @Description Oracle数据库实现类:具体实现类
 */
public class OracleDB implements DB {
    @Override
    public void export() {
        System.out.print("获取Oracle数据 ");
    }
}
  • Data.java
/**
 * @Description 抽象数据类:抽象类
 */
public abstract class Data {

    protected DB db;

    public Data(DB db) {
        this.db = db;
    }

    /**
     * 导出数据
     */
    public abstract void export();
}
  • PdfData.java
/**
 * @Description PDF格式数据:扩充抽象类
 */
public class PdfData extends Data {

    public PdfData(DB db) {
        super(db);
    }

    @Override
    public void export() {
        db.export();
        System.out.println("导出格式为PDF");
    }
}
  • TxtData.java
/**
 * @Description TXT格式数据:扩充抽象类
 */
public class TxtData extends Data {

    public TxtData(DB db) {
        super(db);
    }

    @Override
    public void export() {
        db.export();
        System.out.println("导出格式为TXT");
    }
}
  • XmlData.java
/**
 * @Description XML格式数据:扩充抽象类
 */
public class XmlData extends Data {

    public XmlData(DB db) {
        super(db);
    }

    @Override
    public void export() {
        db.export();
        System.out.println("导出格式为XML");
    }
}
  • Test.java
/**
 * @Description 桥接模式测试类
 */
public class Test {
    public static void main(String[] args) {
        Data txtData = new TxtData(new MysqlDB());
        txtData.export();

        Data pdfData = new PdfData(new MysqlDB());
        pdfData.export();

        Data xmlData = new XmlData(new OracleDB());
        xmlData.export();
    }
}
  • 输出如下:
获取Mysql数据 导出格式为TXT
获取Mysql数据 导出格式为PDF
获取Oracle数据 导出格式为XML
  • 类图如下:

在这里插入图片描述


总结

  • 优点
1.分离抽象部分及其具体实现部分
2.提高了系统的可扩展性
3.符合开闭原则
4.符合合成复用原则
  • 缺点
1.增加了系统的理解和设计难度
2.需要正确地识别出系统中两个独立变化的维度
  • 适用场景
1.抽象和具体实现之间增加更多的灵活性
2.一个类存在两个(或多个)独立变化的维度,且这两个(或多个)维度都需要独立进行扩展
3.不希望使用继承,或因为多层继承导致系统类的个数激增
  • 相关设计模式
1.桥接模式和组合模式
	组合模式强调部分和整体间的组合
	桥接模式强调平行级别上不同类的组合
2.桥接模式和适配器模式
	适配器模式可以把功能上相似,接口不同的类适配起来工作
	桥接模式是把类的抽象和具体实现分离开,在此基础上使这些层次结合起来
  • 桥接模式源代码
Driver(JDBC)

源码


- End -
- 个人学习笔记 -
- 仅供参考 -

标签:Implementor,桥接,db,模式,export,接口,设计模式,public
From: https://www.cnblogs.com/maggieq8324/p/16819131.html

相关文章

  • 装饰模式
    用装饰模式模拟手机功能的升级过程:简单的手机(SimplePhone)在接收来电时,会发出声音提醒主人;而JarPhone除了声音还能振动;更高级的手机(ComplexPhone)除了声音、振动外,还有灯......
  • 外观模式
    在计算机主机(Mainframe)中,只需要按下主机的开机按钮(on()),即可调用其他硬件设备和软件的启动方法,如内存(Memory)的自检(check())、CPU的运行(run())、硬盘(HardDisk)的读......
  • 享元模式
    设计一个围棋软件,在系统中只存在一个白棋对象和一个黑棋对象,但是它们可以在棋盘的不同位置显示多次。   ......
  • 《敏捷软件开发原则、模式与实践》(美)Robert C.Martin著 读书笔记(第一部分 敏捷开发 第
    关键词:《敏捷软件开发原则、模式与实践》,(美)RobertC.Martin,读书笔记,极限编程第二章极限编程概述极限编程(XP)实践1)客户作为团队成员  最好的情况是——客户和开......
  • 云计算的3种服务模式
    1.云基础设施即服务(IaaS):出租处理能力、存储空间、网络容量等基本计算资源。只提供基础的底层资源,用户需要自己安装操作系统、中间件、运行环境、数据、应用程序等。2.云平台......
  • 《敏捷软件开发原则、模式与实践》(美)Robert C.Martin著 读书笔记(第一部分 敏捷开发)
    关键词:《敏捷软件开发》原则、模式与实践》,(美)RobertC.Martin著,读书笔记,敏捷开发,敏捷实践 第一章敏捷实践敏捷联盟。       敏捷宣言:个体和交互......
  • 设计模式之抽象工厂模式
    简介工厂方法模式通过引入工厂等级结构,解决了简单工厂模式中工厂类职责太重的问题,但由于工厂方法模式中的每个工厂只生产一类产品,可能会导致系统中存在大量的工厂类,势必会......
  • Reactor 模式线程模型
    根据Reactor的数据量和处理资源池线程数量,可以分为3钟典型实现单Reactor单线程  单Reactor多线程  主从Reactor多线程 ......
  • 容器5种网络模式 与 K8S pod网络关系
    文档说明:只记录关键地方;理解了容器网络模式,也就知道了如何把多个容器相互连接起来容器的网络模式和跨主机通信:network_mode:"bridge"network_mode:"host"netwo......
  • 创新案例 | Adobe花$200亿重金收购的Figma是如何实践产品驱动增长模式?
    2022年9月15日Adobe宣布斥资约200亿美元收购在线设计协作工具平台Figma,Figma2022年的预计ARR只有4亿美元左右,花了近50倍的价格收购Figma,Adobe显然将协作式原型设计工具视......