当前位置: 首页 > news >正文

设计模式之桥接模式理解

1、基本介绍

  1. 桥接模式(Bridge模式)是指:将实现抽象放在两个不同的类层次中,使两个层 次可以独立改变。
  2. 是一种结构型设计模式
  3. Bridge模式基于类的最小设计原则,通过使用封装、聚合及继承等行为让不同 的类承担不同的职责。
  4. 它的主要特点是把抽象(Abstraction)与行为实现 (Implementation)分离开来,从而可以保持各部分的独立性以及应对他们的功能 扩展

2、原理类图

桥接模式原理类图

原理类图说明

  1. Client 类:桥接模式的调用者
  2. 抽象类(Abstraction) :维护了 Implementor / 即它的实现类 ConcreteImplementorA…, 二者是聚合关系, Abstraction充当桥接类
  1. RefinedAbstraction : 是 Abstraction 抽象类的子类
  2. Implementor : 行为实现类的接口
  3. ConcreteImplementorA /B :行为的具体实现类
  4. 从 UML 图:这里的抽象类和接口是聚合的关系,其实调用和被调用关系

3、以手机品牌与样式为例使用桥接模式

3.1 示例类图

在这里插入图片描述

接口
//品牌类,行为实现的接口
public interface Brand { 
	void open();
	void close();
	void call();
}
接口的具体实现
//小米品牌类,行为的具体实现类
public class XiaoMi implements Brand {
	@Override
	public void open() {
		// TODO Auto-generated method stub
		System.out.println(" 小米手机开机 ");
	}

	@Override
	public void close() {
		// TODO Auto-generated method stub
		System.out.println(" 小米手机关机 ");
	}

	@Override
	public void call() {
		// TODO Auto-generated method stub
		System.out.println(" 小米手机打电话 ");
	}
}
//Vivo品牌类,行为的具体实现类
public class Vivo implements Brand {
	@Override
	public void open() {
		// TODO Auto-generated method stub 
		System.out.println(" Vivo 手机开机 ");
	}
	
	@Override
	public void close() {
		 // TODO Auto-generated method stub
		 System.out.println(" Vivo 手机关机 ");
	}
	
	@Override
	public void call() {
		// TODO Auto-generated method stub 
		System.out.println(" Vivo 手机打电话 ");
	}
}
抽象桥接
//手机类,抽象类充当桥接类
public abstract class Phone {
	//聚合品牌
	private Brand brand;
	
	//构造器
	public Phone(Brand brand) {
		super();
		this.brand = brand;
	}

	protected void open() { 
		this.brand.open();
	}
	protected void close() { 
		brand.close();
	}
	protected void call() {
		 brand.call();
	}
}
抽象的具体实现
//折叠式手机类,继承 抽象类 Phone
public class FoldedPhone extends Phone {
	//构造器
	public FoldedPhone(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(" 折叠样式手机 ");
	}
}
//直立式手机类,继承 抽象类 Phone
public class UpRightPhone extends Phone {

	//构造器
	public UpRightPhone(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 FoldedPhone(new XiaoMi());
		phone1.open(); 
		phone1.call(); 
		phone1.close();
		System.out.println("=======================");
		
		Phone phone2 = new FoldedPhone(new Vivo());
		phone2.open();
		phone2.call();
		 phone2.close();
		System.out.println("==============");
		
		UpRightPhone phone3 = new UpRightPhone(new XiaoMi());
		phone3.open(); 
		phone3.call(); 
		phone3.close();
		System.out.println("==============");
		
		UpRightPhone phone4 = new UpRightPhone(new Vivo());
		phone4.open(); 
		phone4.call(); 
		phone4.close();
	}
}

使用桥接模式后,之后无论是再增加手机样式还是手机品牌,都非常方便。只需要在增加桥接的抽象子类或抽象接口的实现子类。

桥接模式的注意事项和细节

  1. 实现了抽象和实现部分的分离,从而极大的提供了系统的灵活性,让抽象部分和实现部分独立开来,这有助于系统进行分层设计,从而产生更好的结构化系统。
  2. 对于系统的高层部分,只需要知道抽象部分和实现部分的接口就可以了,其它的部分由具体业务来完成。
  3. 桥接模式替代多层继承方案,可以减少子类的个数,降低系统的管理和维护成本。
  4. 桥接模式的引入增加了系统的理解和设计难度,由于聚合关联关系建立在抽象层,要求开发者针对抽象进行设计和编程
  5. 桥接模式要求正确识别出系统中两个独立变化的维度(抽象、和实现),因此其使用范围有一定的局限性,即需要有这样的应用场景。对于那些不希望使用继承或因为多层次继承导致系统类的个数急剧增加的系统,桥接模式尤为适

常见的应用场景:

  • JDBC 驱动程序
  • 银行转账系统
    转账分类: 网上转账,柜台转账,AMT 转账(抽象)
    转账用户类型:普通用户,银卡用户,金卡用户…(实现)
  • 消息管理
    消息类型:即时消息,延时消息(抽象)
    消息分类:手机短信,邮件消息,QQ 消息…(实现)

相关文章:

  • 设计模式之适配器模式理解
  • 今天又一项目采用保证金服务——CSDN外包实践(32)
  • 设计模式之装饰者模式
  • 一本“由厚变薄”的好书
  • 设计模式之组合模式
  • 设计模式之外观模式详解(Facade Pattern)
  • 优化系统七十项Reg文件
  • 设计模式之享元模式详解(FlyWeight Pattern)
  • 设计模式之代理模式详解(Proxy Pattern)
  • 又见林锐
  • 设计模式之模板方法模式详解(Template Method Pattern)
  • 工作苦旅
  • 设计模式之命令模式详解(Command Pattern)
  • 今天试用了VE开发SWT
  • 设计模式之访问者模式详解(Visitor Pattern)
  • 【干货分享】SpringCloud微服务架构分布式组件如何共享session对象
  • 77. Combinations
  • Android系统模拟器绘制实现概述
  • CSS3 变换
  • es6
  • export和import的用法总结
  • iOS仿今日头条、壁纸应用、筛选分类、三方微博、颜色填充等源码
  • Linux学习笔记6-使用fdisk进行磁盘管理
  • Python进阶细节
  • 回顾2016
  • 记一次删除Git记录中的大文件的过程
  • 前端每日实战:70# 视频演示如何用纯 CSS 创作一只徘徊的果冻怪兽
  • 全栈开发——Linux
  • 什么软件可以剪辑音乐?
  • 通过来模仿稀土掘金个人页面的布局来学习使用CoordinatorLayout
  • 网络应用优化——时延与带宽
  • 微信开源mars源码分析1—上层samples分析
  • 学习使用ExpressJS 4.0中的新Router
  • # Pytorch 中可以直接调用的Loss Functions总结:
  • (01)ORB-SLAM2源码无死角解析-(56) 闭环线程→计算Sim3:理论推导(1)求解s,t
  • (Matlab)基于蝙蝠算法实现电力系统经济调度
  • (二)换源+apt-get基础配置+搜狗拼音
  • (十)DDRC架构组成、效率Efficiency及功能实现
  • (实战篇)如何缓存数据
  • (一)Linux+Windows下安装ffmpeg
  • (转)AS3正则:元子符,元序列,标志,数量表达符
  • (转)自己动手搭建Nginx+memcache+xdebug+php运行环境绿色版 For windows版
  • (转载)在C#用WM_COPYDATA消息来实现两个进程之间传递数据
  • (轉貼) UML中文FAQ (OO) (UML)
  • .net MySql
  • .Net 转战 Android 4.4 日常笔记(4)--按钮事件和国际化
  • /etc/apt/sources.list 和 /etc/apt/sources.list.d
  • [ 代码审计篇 ] 代码审计案例详解(一) SQL注入代码审计案例
  • [C# WPF] DataGrid选中行或选中单元格的背景和字体颜色修改
  • [C#] 基于 yield 语句的迭代器逻辑懒执行
  • [C#][DevPress]事件委托的使用
  • [DL]深度学习_Feature Pyramid Network
  • [Git].gitignore失效的原因
  • [GXYCTF2019]禁止套娃
  • [hdu 4552] 怪盗基德的挑战书