桥接模式:探索JDBC的接口

一、目录概要

二、问题探究

需求:假设要设计一个电脑商场管理系统的某个模块设计,电脑分为品牌和类型两个纬度,我们应该怎么解决?

按照初学者的思路,利用继承就能简单粗暴的实现,那我们来看下这种思路的设计类图。

从电脑纬度划分

package com.aaron.bridge;

public interface Computer {
    public void sale();
}

class Desktop implements Computer{
    @Override
    public void sale() {
        System.out.println("台式电脑");
    }
}

class Laptop implements Computer{
    @Override
    public void sale() {
        System.out.println("笔记本电脑");
    }
}

class Pad implements Computer{
    @Override
    public void sale() {
        System.out.println("平板电脑");
    }
}

从品牌纬度划分

package com.aaron.bridge;
// 宏碁品牌的三种类型
public class AcerDesktop extends Desktop{
    @Override
    public void sale() {
        System.out.println("宏碁台式机");
    }
}

class AcerLaptop extends Laptop{
    @Override
    public void sale() {
        System.out.println("宏碁笔记本电脑");
    }
}

class AcerPad extends Pad{
    @Override
    public void sale() {
        System.out.println("宏碁平板电脑");
    }
}
package com.aaron.bridge;

// 苹果品牌的三种类型
public class AppleDesktop extends Desktop{
    @Override
    public void sale() {
        System.out.println("苹果台式机");
    }
}

class AppleLaptop extends Laptop{
    @Override
    public void sale() {
        System.out.println("苹果笔记本电脑");
    }
}

class ApplePad extends Pad{
    @Override
    public void sale() {
        System.out.println("苹果平板电脑");
    }
}
package com.aaron.bridge;

//戴尔品牌的三种类型
public class DellDesktop extends Desktop{
    @Override
    public void sale() {
        System.out.println("戴尔台式机");
    }
}

class DellLaptop extends Laptop{
    @Override
    public void sale() {
        System.out.println("戴尔笔记本电脑");
    }
}

class DellPad extends Pad{
    @Override
    public void sale() {
        System.out.println("戴尔平板电脑");
    }
}

问题1:假设我们的系统按照上述思路设计,当我们新增一个品牌的时候,怎么办?

根据上述思路,从品牌纬度扩展品牌时直接新增台式机、笔记本电脑、平板电脑的类即可。

问题2:当我们新增一个机器类型的时候又该怎么办?
根据上述思路,在机器纬度类型扩展。

  1. 添加新的电脑机型。
  2. 在所有的品牌中,都新增新的机型。
package com.aaron.bridge;

// 电脑纬度
public interface Computer {
    public void sale();
}

class Desktop implements Computer{
    @Override
    public void sale() {
        System.out.println("台式电脑");
    }
}

class Laptop implements Computer{
    @Override
    public void sale() {
        System.out.println("笔记本电脑");
    }
}

class Pad implements Computer{
    @Override
    public void sale() {
        System.out.println("平板电脑");
    }
}

class MaxPad implements Computer{
    @Override
    public void sale() {
        System.out.println("超大屏电脑");
    }
}

// 品牌纬度
public class DellDesktop extends Desktop{
    @Override
    public void sale() {
        System.out.println("戴尔台式机");
    }
}

class DellLaptop extends Laptop{
    @Override
    public void sale() {
        System.out.println("戴尔笔记本电脑");
    }
}

class DellPad extends Pad{
    @Override
    public void sale() {
        System.out.println("戴尔平板电脑");
    }
}

class DellPad extends Pad{
    @Override
    public void sale() {
        System.out.println("戴尔平板电脑");
    }
}

class DellMaxPad extends Pad{
    @Override
    public void sale() {
        System.out.println("超大屏平板电脑");
    }
}

思考:当我们添加少量的机型和品牌的时候,该方案的代码扩展性还是可以接受的。但是,再往远思考一步。

  1. 假设电脑商城,添加10个品牌,再添加10种机型,怎么办?
  2. 系统已经上线,系统处于维护阶段人力有限,怎么办?

问题:上述问题主要是把电脑和品牌两个纬度耦合。

  1. 违背单一职责原则(一个类只由一个维度影响)
  2. 违背开闭原则(对拓展开放,对修改关闭)。

解决:将机器、品牌两个纬度进行拆分,不要将他们耦合。

三、解决思路

3.1 什么是桥接模式?

将两个维度(抽象、实现)分离,使它们都可以独立地变化。

3.2 桥接模式的分析
  1. 类型:台式机、笔记本电脑、平板电脑。
  2. 品牌:宏碁、苹果、戴尔。

关键:将上述问题拆分成两个纬度类型和品牌。我们刚刚也讨论了,主要解决拓展性问题。当添加一个新的机器类型或者品牌的时候,不会对其他机器类型或者品牌产生影响。

概念:简单谈下概念,重点根据类图和实现代码去理解Abstraction、RefinedAbstraction、Implementor、ConcreteImplementor

Abstraction:抽象部分的接口。通常在这个对象里面,要维护一个实现部分的对象引用,在抽象对象里面的方法,需要调用实现部分的对象来完成。这个对象里面的方法,通常都是跟具体的业务相关的方法。

RefinedAbstraction:
扩展抽象部分的接口,通常在这些对象里面,定义跟实际业务相关的方法,这些方法的实现通常会使用Abstraction中定义的方法,也可能需要调用实现部分的对象来完成。

Implementor:
定义实现部分的接口,这个接口不用和Abstraction里面的方法一致(根据约定优于配置原则,建议跟Abstraction一致。),通常是由Implementor接口提供基本的操作,而Abstraction里面定义的是基于这些基本操作的业务方法,也就是说Abstraction定义了基于这些基本操作的较高层次的操作。

ConcreteImplementor:
真正实现Implementor接口的对象。

3.3 桥接模式实现

1、实体部分设计

package com.aaron.bridge;

/**
 *
 * @author xiaoyongAaron
 * 品牌纬度-实现部分接口
 */
public interface ImplementorBrand {
    public void sale();
}

class  ConcreteImplementorAcer implements ImplementorBrand{

    @Override
    public void sale() {
        System.out.println("宏碁品牌");
    }
}

class ConcreteImplementorApple implements ImplementorBrand{
    @Override
    public void sale() {
        System.out.println("苹果品牌");
    }
}

class ConcreteImplementorDell implements ImplementorBrand{
    @Override
    public void sale() {
        System.out.println("戴尔品牌");
    }
}

2、抽象部分设计

package com.aaron.bridge;

/**
 * 机器类型纬度-抽象部分
 * @author xiaoyongAaron
 */
public class AbstractionComputer {
     protected ImplementorBrand brand;

     public AbstractionComputer(ImplementorBrand brand){
         this.brand=brand;
     }

     public void sale(){
        brand.sale();
     };

}

/**
 * 扩展部分
 * @author xiaoyongAaron
 */
class RefinedAbstractionDesktop extends AbstractionComputer{
    public RefinedAbstractionDesktop(ImplementorBrand brand) {
        super(brand);
    }

    @Override
    public void sale() {
        //添加自己的特性,实际业务。
        paly();
        super.sale();
    }

    public void paly(){
        System.out.println("我台式机抗摔打");
    }
}

class RefinedAbstractionLaptop extends AbstractionComputer{
    public RefinedAbstractionLaptop(ImplementorBrand brand) {
        super(brand);
    }

    @Override
    public void sale() {
        //添加自己的特性,实际业务。
        lighting();
        super.sale();
    }

    public void lighting(){
        System.out.println("我笔记本电脑充电5分钟,续航5小时");
    }
}

class RefinedAbstractionPad extends AbstractionComputer{
    public RefinedAbstractionPad(ImplementorBrand brand) {
        super(brand);
    }

    @Override
    public void sale() {
        //添加自己的特性,实际业务。
        weighting();
        super.sale();
    }

    public void weighting(){
        System.out.println("我平板电脑便于携带");
    }
}

4、执行结果显示

四、问题回顾

4.1 什么是桥接模式、为什么要桥接?

简单说桥接模式就是把两个纬度分离,所以说当我们在实际开发的时候,遇到两个维度问题的时候,直接条件反射桥接模式。

就像上述问题,当有两个维度(品牌+机器类型)赋予给一个类的时候,基于单一职责原则,需要把它们解耦。那通过上述范例可知,那么我们就需要一座桥一样,把两个纬度用一个中间物(类或者接口)把它们关联起来,从而达到我们的目的。

4.2 桥接模式怎么接?

核心:如何把Implementor对象传递到抽象接口。

  1. 如上述描述,利用构造函数传参。
  2. 创造无参构造函数,添加get、set方法。
  3. 工厂模式:参考设计模式的工厂模式。
  4. IOC控制反转,最经典的就是Spring容器。内部的实现原理原本创建对象都是由我们自己管理,但是把这一步骤交给容器管理,就不用我们担心了。例如在JDBC的设计当中,充当这个角色的就是DriverManage去把对象注入在抽象接口当中。
4.3 桥接模式本质和经验
  1. 本质:抽象与实现(两个纬度)分离。
  2. 多用对象组合(has-A),少用继承。
  3. 开闭原则:我们应该对代码拓展开放,拒绝代码修改。

实际应用场景:

作者:码农皮邱
原文:https://www.cnblogs.com/qiuyong/p/11107180.html
推荐:您的支持是对博主深入思考总结的最大鼓励,要是有需要关注公众号与作者面对面对话交流~
说明:本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接,尊重作者的劳动成果。

原文地址:https://www.cnblogs.com/qiuyong/p/11107180.html

时间: 2024-08-30 13:59:55

桥接模式:探索JDBC的接口的相关文章

设计模式(7)--Bridge(桥接模式)--结构型

1.模式定义: 桥接模式是对象的结构模式.又称为柄体(Handle and Body)模式或接口(Interface)模式.桥接模式的用意是“将抽象化(Abstraction)与实现化(Implementation)脱耦,使得二者可以独立地变化”. 2.模式特点: 桥接模式虽然不是一个使用频率很高的模式,但是熟悉这个模式对于理解面向对象的设计原则,包括“开-闭”原则以及组合/聚合复用原则都很有帮助.理解好这两个原则,有助于形成正确的设计思想和培养良好的设计风格. 桥接模式的用意是“将抽象化(Ab

图解Java设计模式之桥接模式

图解Java设计模式之桥接模式 手机操作问题 传统方案解决手机操作问题 传统方案解决手机操作问题分析 桥接模式(Bridge)-基本介绍 桥接模式解决手机操作问题 桥接模式在JDBC中的源码解析 桥接模式的注意事项和细节 桥接模式其它应用场景 手机操作问题 现在对不同手机类型的不同品牌实现操作编程(比如 :开机.关机.上网.打电话等等),如图 : 传统方案解决手机操作问题 传统方法对应的类图 传统方案解决手机操作问题分析 1)扩展性问题(类爆炸),如果我们再增加手机的样式(旋转式),就需要增加各

[Unity 设计模式]桥接模式(BridgePattern)

1.前言 继上一讲IOC模式的基础上继续本讲桥接模式,笔者感觉桥接模式是23种设计模式中桥接模式是最好用但也是最难理解的设计模式之一,23中设计模式就好武侠剧中一本武功秘籍,我们在工作过程中想要熟练运用其中的每一种设计模式就好比跟高手过招想要能运用好武侠秘籍中的每一招每一式,并且能随着对手出招的不同我们能随机应变对应的招数,这就要求我们对每一种设计模式都理解的非常深刻才能运用自如,打出组合拳的效果. 2.需求 我们在FPS类游戏中会碰到这样的需求——实现武器和角色,无论是敌人还是我方角色都能通过

设计模式【7】:桥接模式【接口适配】

1,定义 Gof23设计模式中是这样定义桥接设计模式:桥接模式的目的是把抽象层次结构从其实现中分离出来,使其能够独立变更.抽象层定义了供客户端使用的上层的抽象接口.实现层次结构定义了供抽象层次使用的底层接口.实现类的引用被封装于抽象类的实例中时,桥接就形成了. 我们用一个游戏的例子去理解这个桥接模式,比如,我们假如魂斗罗一代,魂斗罗二代界面没多大变化,可以共用一套底层接口. 上面这个图:左侧部分Abstraction是抽象类,右侧部分是实现类. 按照定义,实现类应该是实现具体的底层接口,我们都知

桥接模式

一.目录概要 二.场景问题 假设要设计一个电脑商场管理系统的某个模块设计,电脑分为品牌和类型两个纬度,我们应该怎么解决?我们初学者最容易想到的办法就是利用继承的方式,那利用继承实现的类图又是什么样子呢?我们看图. 代码展示 package com.aaron.bridge; public interface Computer { public void sale(); } class Desktop implements Computer{ @Override public void sale(

桥接模式(Bridge)

一.桥接模式介绍: 桥接模式:将抽象部分与它的实现部分分离,使它们都可以独立的变化.而不会直接影响到其他部分. 未使用桥接模式的抽象与实现结构图(如下): 如果要增加一个apple品牌的电脑,则需要在台式机下新增一个apple的台式机 在笔记本下新增一个apple笔记本,在pad下新增一个apple的pad.代码比较繁琐. 如果使用桥接模式(如下图),使抽象部分和抽象的派生(实现)部分分离出来,这样让它们各自的变化,这样每种实现就不会影响到其他实现.从而达到对应变化的目的 将电脑类型作为一个维度

设计模式(七)桥接模式

核心要点:处理多层继承结构,处理多维度变化的场景,将各个维度设计成独立的继承结构,使各个维度可以独立的扩展在抽象层建立关联. 桥接模式可以取代多层继承的方案.多层继承违背了单一职责原则,复用性较差,类的个数也非常多.桥接模式可以极大的减少子类的个数,从而降低管理和维护的成本. 桥接模式极大的提高了系统可扩展性,在两个变化维度中任意扩展一个维度,都不需要修改原有的系统,符合开闭原则. 如上图所示,用多层继承结构可以实现,但会出现扩展性问题以及违反单一职责原则(一个类,有两个引起这个类变化的原因)

JAVA设计模式之 桥接模式【Bridge Pattern】

一.概述 将抽象部分与它的实现部分分离,使它们都可以独立地变化.它是一种对象结构型模式,又称为柄体(Handle and Body)模式. 二.适用场景 处理多维度变化. 业务场景:某功能为将数据库中的数据转换成多种文件格式,例如txt.xml.pdf等格式,同时需要支持多种不同类型的数据库的读取.便可使用桥接模式对其进行设计. 这里的维度有两个 分别为:不同的文件格式 和 不同的数据库类型.如下图: 三.UML类图 桥接模式通用结构图: 针对上面的业务场景-桥接模式-示例结构图: 四.参与者

设计模式入门之桥接模式Bridge

//桥接模式定义:将抽象部分与它的实现部分分离,使得他们都可以独立地变化 //广义来讲,桥接模式非常普遍,面向抽象编程,面向接口编程就可以看作是他的体现 //实例:一个系统,要按照不同的要求发信息(普通,加急,特急),而且还要以不同的方式发送(站内信,Email,短信)等,考虑到其扩展性,用桥接模式再合适不过了 //上代码 //桥接的一半---抽象部分 public abstract class AbstractionMessage { protected MessageImplementor