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

目录
  • 引例
  • 桥接模式
  • 实战示例
    • 代码:
  • 总结

引例

需求:对不同手机类型的不同品牌(比如按键手机:诺基亚、翻盖手机:纽曼、智能手机:华为、小米)实现操作编程(比如: 开机、关机、打电话)。

先来说说一般解法:将不同手机类型继承父类手机,最后各个品牌再继承对应手机类型:

弊端:乍一看没问题,但其实不易扩展(类爆炸),如果增加新的手机类型(比如新兴的折叠式),就需要增加各个手机品牌的类去继承(比如已继承智能手机的华为小米)。同样如果我们增加一个手机品牌,也要在各个手机样式类下增加。违反了单一职责原则,维护成本高。

解决方案就是下面的主角:桥接模式。

桥接模式

桥接模式(Bridge)是一种结构型设计模式。顾名思义,就像搭个桥连接起来,通过使用封装、聚合及继承等行为让不同的类承担不同的职责,将实现与抽象放在两个不同的类层次中,使两个层次可以独立改变,保持各部分的独立性以及应对他们的功能扩展。

原理类图:

  • Client类:客户端调用
  • Abstraction抽象类:充当桥接类,维护了Implementor接口(即它的实现类ConcreteImplementorA…)
  • RefindAbstraction类:是抽象类的子类
  • Implementor接口:行为实现接口
  • ConcreteImplementorA/B类:行为的具体实现类

从UML类图看出,抽象类和接口是聚合的关系,即调用和被调用的关系。如此一来搭好桥后,具体实现类调用方法=》父类抽象类的方法=》行为接口方法=》具体接口行为实现类,以完成连接,同时两者又相互独立易扩展:

实战示例

用桥接模式来解决引例的实际问题。

类图:

代码:

//接口
public interface Brand {
	void open(); //开机
	void close(); //关机
	void call();//打电话
}
//接口实现类
public class NOKIA implements Brand{
    @Override
    public void open() {
        System.out.println("诺基亚手机开机");
    }
    @Override
    public void close() {
        System.out.println("诺基亚手机关机");
    }
    @Override
    public void call() {
        System.out.println("诺基亚手机打电话");
    }
}
public class Newsmy implements Brand{
    @Override
    public void open() {
        System.out.println("纽曼手机开机");
    }
    @Override
    public void close() {
        System.out.println("纽曼手机关机");
    }
    @Override
    public void call() {
        System.out.println("纽曼手机打电话");
    }
}
public class Huawei implements Brand{
    @Override
    public void open() {
        System.out.println("华为手机开机");
    }
    @Override
    public void close() {
        System.out.println("华为手机关机");
    }
    @Override
    public void call() {
        System.out.println("华为手机打电话");
    }
}
public class Xiaomi implements Brand{
    @Override
    public void open() {
        System.out.println("小米手机开机");
    }
    @Override
    public void close() {
        System.out.println("小米手机关机");
    }
    @Override
    public void call() {
        System.out.println("小米手机打电话");
    }
}
//抽象类
public abstract class Phone {
	private Brand brand;//手机品牌接口
	public Phone(Brand brand) {//构造器
		super();
		this.brand = brand;
	}
	public void open() {
		this.brand.open();
	}
	public void close() {
		this.brand.close();
	}
	public void call() { this.brand.call(); }
}
//抽象子类
public class ButtonPhone extends Phone{
    public ButtonPhone(Brand brand) {
        super(brand);
    }
    public void open() {
        super.open();
        System.out.println("按键手机");
    }
    public void close() {
        super.close();
        System.out.println("按键手机");
    }
    public void call() {
        super.call();
        System.out.println("按键手机");
    }
}
public class SlidePhone extends Phone{
    public SlidePhone(Brand brand) {
        super(brand);
    }
    public void open() {
        super.open();
        System.out.println("翻盖手机");
    }
    public void close() {
        super.close();
        System.out.println("翻盖手机");
    }
    public void call() {
        super.call();
        System.out.println("翻盖手机");
    }
}
public class SmartPhone  extends Phone{
    public SmartPhone(Brand brand) {
        super(brand);
    }
    public void open() {
        super.open();
        System.out.println("智能手机");
    }
    public void close() {
        super.close();
        System.out.println("智能手机");
    }
    public void call() {
        super.call();
        System.out.println("智能手机");
    }
}
//客户端调用
public class Client {
    public static void main(String[] args) {
        Phone phone1 = new ButtonPhone(new NOKIA());
        phone1.open();
        phone1.call();
        phone1.close();
        System.out.println("=======================");
        Phone phone2 = new SlidePhone(new Newsmy());
        phone2.open();
        phone2.call();
        phone2.close();
        System.out.println("=======================");
        Phone phone3 = new SmartPhone(new Huawei());
        phone3.open();
        phone3.call();
        phone3.close();
    }
}

总结

  • 实现了抽象和实现部分的分离,从而极大的提供了系统的灵活性,让抽象部分和实现部分独立开来,这有助于系统进行分层设计,从而产生更好的结构化系统。
  • 桥接模式替代多层继承方案,可以减少子类的个数,降低系统的管理和维护成本。
  • 桥接模式的引入增加了系统的理解和设计难度,由于聚合关联关系建立在抽象层,要求开发者针对抽象进行设计和编程
  • 常见的应用场景: -JDBC驱动程序

-银行转账系统

转账分类: 网上转账,柜台转账,AMT转账

转账用户类型:普通用户,银卡用户,金卡用户…

-消息管理

消息类型:即时消息,延时消息

消息分类:手机短信,邮件消息,QQ消息…

本篇文章就到这里了,希望能给你带来帮助,也希望您能够多多关注我们的更多内容!

(0)

相关推荐

  • java设计模式-单例模式实现方法详解

    目录 饿汉式 静态变量 静态代码块 懒汉式 线程不安全 线程安全 双重检查 静态内部类 总结 a 饿汉式 所谓饿汉式,就是直接创建出类的实例化,然后用private私有化,对外只用静态方法暴露. 静态变量 步骤 构造器私有化 类的内部创建对象 向外暴露一个静态的公共方法 优点 缺点 写法简单,在类装载的时完成实例化,避免了线程同步问题 类装载时完成实例化,没有达到LazyLoading的效果,若该实例从未使用,则会造成内存浪费 class Singleton { //私有化构造器 private

  • Java设计模式之桥接模式的实现

    桥接模式 桥接模式是将抽象部分与它的实现部分分离,使他们都可以独立地变化.它是一种对象结构型模式,又称为柄体(Handle and Body)模式或接口(Interface)模式. 上图一个类被三个类继承,使我们的程序扩展性,可维护性低,违反了单一职责原则. 具体代码实现如下: 1.创建品牌接口 package com.jialidun.gof.birdge; //品牌 public interface Brand { void info(); } 2.创建计算机的抽象类 package com

  • Java设计模式之桥接模式实例详解

    本文实例讲述了Java设计模式之桥接模式.分享给大家供大家参考,具体如下: 概念: 桥接模式(Bridge Pattern):将抽象部分与它的实现部分分离,使它们都可以独立地变化. 桥接模式将继承关系转换为关联关系,从而降低了类与类之间的耦合,减少了代码编写量. 什么情况下会用桥接模式? 简单的说就是我们在抽象对象的特征时,对象的特征属性又很抽象,不得不把属性再次抽象. 否则的话,具体子类的数量将会成几何增长,而且不易扩展.没办法维护现有代码. 举例,我们在抽象手机这二个对象时,它的几个属性,如

  • java设计模式之桥接模式(Bridge)

    概述 桥接模式一种结构型模式,它主要应对的是:由于实际的需要,某个类具有两个或以上的维度变化,如果只是用继承将无法实现这种需要,或者使得设计变得相当臃肿. 桥接模式的做法是把变化的部分抽象出来,使变化部分与主类分离开来,从而将多个维度的变化彻底分离.最后,提供一个管理类来组合不同维度上的变化,通过这种组合来满足业务的需要. UML结构图 代码示例 package interview; interface Implementor{ void operationImpl(); } abstract

  • java设计模式-组合模式详解

    目录 组合模式 Demo 代码: 总结 组合模式 组合模式(Composite Pattern)又叫部分整体模式,是用于把一组相似的对象当作一个单一的对象.组合模式依据树形结构来组合对象,用来表示部分以及整体层次.这种类型的设计模式属于结构型模式,它创建了对象组的树形结构. 主要解决:它在我们树型结构的问题中,模糊了简单元素和复杂元素的概念,客户程序可以像处理简单元素一样来处理复杂元素,从而使得客户程序与复杂元素的内部结构解耦. 如何解决:树枝和叶子实现统一接口,树枝内部组合该接口. 何时使用:

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

    目录 引例 桥接模式 实战示例 代码: 总结 引例 需求:对不同手机类型的不同品牌(比如按键手机:诺基亚.翻盖手机:纽曼.智能手机:华为.小米)实现操作编程(比如: 开机.关机.打电话). 先来说说一般解法:将不同手机类型继承父类手机,最后各个品牌再继承对应手机类型: 弊端:乍一看没问题,但其实不易扩展(类爆炸),如果增加新的手机类型(比如新兴的折叠式),就需要增加各个手机品牌的类去继承(比如已继承智能手机的华为小米).同样如果我们增加一个手机品牌,也要在各个手机样式类下增加.违反了单一职责原则

  • java设计模式--原型模式详解

    目录 引例 原型模式 浅拷贝 在原先Sheep类基础上实现Cloneable接口,重写clone方法. 客户端调用 Sheep类 新添的Cow类 客户端调用克隆 深拷贝 1.Cow类也实现Cloneable接口 Sheep类的clone再添加调用cow的clone 客户端调用 1.Cow类实现序列化接口,不必实现Cloneable接口了 2.在Sheep类实现序列化接口 3.客户端调用 总结 引例 问题: 现在有一只羊(包含属性:名字Dolly.年龄2),需要克隆10只属性完全相同的羊. 一般解

  • java设计模式--策略模式详解

    目录 策略模式 Demo 代码: 总结 策略模式 策略模式(Strategy Pattern)属于行为型模式,指对象有某个行为,但是在不同的场景中,该行为有不同的实现算法.用算法族分别封装起来,实现同一个接口,让他们之间可以互相替换,让算法的变化独立于使用算法的客户. 主要解决:在有多种算法相似的情况下,使用 if-else 所带来的复杂和难以维护. 如何解决:将这些算法封装成一个一个的类,任意地替换. 何时使用:一个系统有许多许多类,而区分它们的只是他们直接的行为. 使用场景: 如果在一个系统

  • java设计模式--建造者模式详解

    目录 引例 一般解法 代码: AbstractHouse(房子) Bungalow(平房) Villa (别墅) 客户端调用 建造者模式 建造者模式解法 代码: House类(Product产品) HouseBuilder类(Builder抽象建造者) 3.Bungalow类(ConcreteBuilder具体建造者A) 4.Villa类(ConcreteBuilder具体建造者B) 5.HouseDirector类(Director指挥者) 客户端调用 总结 引例 需求:建造房子,建造过程包括

  • Java之dao模式详解及代码示例

    什么是dao模式? DAO(Data Access Object)顾名思义是一个为数据库或其他持久化机制提供了抽象接口的对象,在不暴露底层持久化方案实现细节的前提下提供了各种数据访问操作.在实际的开发中,应该将所有对数据源的访问操作进行抽象化后封装在一个公共API中.用程序设计语言来说,就是建立一个接口,接口中定义了此应用程序中将会用到的所有事务方法.在这个应用程序中,当需要和数据源进行交互的时候则使用这个接口,并且编写一个单独的类来实现这个接口,在逻辑上该类对应一个特定的数据存储.DAO模式实

  • Java设计模式之装饰模式详解

    一.装饰模式引入例子 一个快餐店计算价格问题举例: 快餐店有炒面.炒饭这些快餐,可以额外附加鸡蛋.火腿.培根这些配菜,加配菜需要额外加钱,并且每个配菜的价钱不一样,计算快餐价格如何实现? 1.1 一般设计 1.2 使用继承方式的一般设计存在的问题 横向扩展性不好:如果要再加一种配料(火腿肠),我们就会发现需要给FriedRice和FriedNoodles分别定义一个子类.如果要新增一个快餐品类(炒河粉)的话,就需要定义更多的子,会出现类爆炸的问题. 继承适合于纵向扩展 二.装饰模式 2.1 装饰

  • Java设计模式之模板方法详解

    目录 概念 核心设计要点 优缺点 应用场景 模板方法和策略模式的区别 代码案例 概念 模板方法模式是所有模式中最为常见的几个模式之一,是基于继承的代码复用的基本技术,没有关联关系.因此,在模板方法模式的类结构图中,只有继承关系. 核心设计要点 AbstractClass:抽象类,定义并实现一个模板方法.这个模板方法定义了算法的骨架,而逻辑的组成步骤在相应的抽象操作中,推迟到子类去实现. ConcreteClass:实现实现父类所定义的一个或多个抽象方法.. 优缺点 优点 利用模板方法将相同处理逻

  • Java 设计模式之适配器模式详解

    目录 定义 结构图 使用场景 代码实现 Java代码实现 Python代码实现 定义 适配器将一个类的接口,转换成客户期望另一个接口.适配器让原本不兼容的类可以合作无间 结构图 如图所示,两脚插头如何能插入三脚插座,可以在中间加一个适配器进行转换,就能实现两脚插头能插入三脚插座. 使用场景 新的代码兼容旧的代码 使用别人好的代码到自己的代码中 代码实现 适配器模式有:对象适配器和类适配器 Java代码实现 java没有多继承,只能实现对象适配器 先创建两个接口 // 适配目标接口 public

  • Java设计模式之java桥接模式详解

    目录 一.什么是桥接模式: 二.UML结构图: 三.代码实现: 四.JDBC源码解析-桥接模式: 1.源码分析: 2.源码类图: 3.对 JDBC 的观点: 参考博客: 总结 一.什么是桥接模式: 桥接,顾名思义,就是用来连接两个部分,使得两个部分可以互相通讯,桥接模式的作用就是为被分离的抽象部分和实现部分搭桥.在现实生活中一个物品在搭配不同的配件时会产生不同的动作和结果,例如一辆赛车搭配的是硬胎或者是软胎就能够在干燥的马路上行驶,而如果要在下雨的路面行驶,就需要搭配雨胎了,这种根据行驶的路面不

随机推荐