设计模式(7)--Bridge(桥接模式)--结构型
1.模式定义:
2.模式特点:
(1)抽象化
(2)实现化
(3)脱耦
- 桥接模式使用对象见的组合关系解耦了抽象和实现之间固有的绑定关系,使得抽象和实现可以沿着各自的维度来变化。
- 所谓抽象和实现沿着各自维度的变化,即“子类化”它们,得到各个子类之后,便可以任意它们,从而获得不同路上的不同其次。
- 桥接模式有时候类似于多继承方案,但是多继承方案往往违背了SRP原则,复用性较差。桥接模式是比继承方案更好的解决方法。
- 桥接模式的应用一般在“两个非常强的变化维度”,有时候即使有两个变化的维度,但是某个方向的变化维度并不剧烈——换而言之两个变化不会导致纵横交错的结果,并不一定要使用桥接模式。
3.使用场景:
4.模式实现:

(1)抽象化(Abstraction)角色:
public abstract class Abstraction {
protected Implementor impl;
public Abstraction(Implementor impl){
this.impl = impl;
}
//示例方法
public void operation(){
impl.operationImpl();
}
}
(2)修正抽象化(RefinedAbstraction)角色:
public class RefinedAbstraction extends Abstraction {
public RefinedAbstraction(Implementor impl) {
super(impl);
}
//其他的操作方法
public void otherOperation(){
}
}
(3)实现化(Implementor)角色:
public abstract class Implementor {
/**
* 示例方法,实现抽象部分需要的某些具体功能
*/
public abstract void operationImpl();
}
(4)具体实现化(ConcreteImplementor)角色:
public class ConcreteImplementorA extends Implementor {
@Override
public void operationImpl() {
//具体操作
}
}
public class ConcreteImplementorB extends Implementor {
@Override
public void operationImpl() {
//具体操作
}
}
5.优缺点:
(1)桥接模式的优点
[1]实现了抽象和实现部分的分离
[2]更好的可扩展性
[3]可动态的切换实现
[4]实现细节对客户端透明,可以对用户隐藏实现细节。
(2)桥接模式的缺点
[1]]桥接模式的引入会增加系统的理解与设计难度,由于聚合关联关系建立在抽象层,要求开发者针对抽象进行设计与编程。
[2]桥接模式要求正确识别出系统中两个独立变化的维度,因此其使用范围具有一定的局限性。
6.注意事项
7.应用实例:
(1)不使用桥接模式:

[1]消息的统一接口
public interface Message {
/**
* 发送消息
* @param message 要发送消息的内容
* @param toUser 消息的接受者
*/
public void send(String message , String toUser);
}
[2]系统内短消息示例类
public class CommonMessageSMS implements Message {
@Override
public void send(String message, String toUser) {
System.out.println("使用系统内短消息的方法,发送消息'"+message+"'给"+toUser);
}
}
[3]邮件消息示例类
public class CommonMessageEmail implements Message{
@Override
public void send(String message, String toUser) {
System.out.println("使用邮件短消息的方法,发送消息'"+message+"'给"+toUser);
}
}

[1]加急消息的接口
public interface UrgencyMessage extends Message {
/**
* 监控指定消息的处理过程
* @param messageId 被监控的消息编号
* @return 监控到的消息的处理状态
*/
public Object watch(String messageId);
}
[2]系统内加急短消息示例类
public class UrgencyMessageSMS implements UrgencyMessage {
@Override
public Object watch(String messageId) {
// 根据消息id获取消息的状态,组织成监控的数据对象,然后返回
return null;
}
@Override
public void send(String message, String toUser) {
message = "加急:" + message;
System.out.println("使用系统内短消息的方法,发送消息'"+message+"'给"+toUser);
}
}
[3]邮件加急短消息示例类
public class UrgencyMessageEmail implements UrgencyMessage {
@Override
public Object watch(String messageId) {
// 根据消息id获取消息的状态,组织成监控的数据对象,然后返回
return null;
}
@Override
public void send(String message, String toUser) {
message = "加急:" + message;
System.out.println("使用邮件短消息的方法,发送消息'"+message+"'给"+toUser);
}
}




[1]抽象消息类
public abstract class AbstractMessage {
//持有一个实现部分的对象
MessageImplementor impl;
/**
* 构造方法,传入实现部分的对象
* @param impl 实现部分的对象
*/
public AbstractMessage(MessageImplementor impl){
this.impl = impl;
}
/**
* 发送消息,委派给实现部分的方法
* @param message 要发送消息的内容
* @param toUser 消息的接受者
*/
public void sendMessage(String message , String toUser){
this.impl.send(message, toUser);
}
}
[2]普通消息类
public class CommonMessage extends AbstractMessage {
public CommonMessage(MessageImplementor impl) {
super(impl);
}
@Override
public void sendMessage(String message, String toUser) {
// 对于普通消息,直接调用父类方法,发送消息即可
super.sendMessage(message, toUser);
}
}
[3]加急消息类
public class UrgencyMessage extends AbstractMessage {
public UrgencyMessage(MessageImplementor impl) {
super(impl);
}
@Override
public void sendMessage(String message, String toUser) {
message = "加急:" + message;
super.sendMessage(message, toUser);
}
/**
* 扩展自己的新功能,监控某消息的处理状态
* @param messageId 被监控的消息编号
* @return 监控到的消息的处理状态
*/
public Object watch(String messageId) {
// 根据消息id获取消息的状态,组织成监控的数据对象,然后返回
return null;
}
}
[4]实现发送消息的统一接口
public interface MessageImplementor {
/**
* 发送消息
* @param message 要发送消息的内容
* @param toUser 消息的接受者
*/
public void send(String message , String toUser);
}
[5]系统内短消息的实现类
public class MessageSMS implements MessageImplementor {
@Override
public void send(String message, String toUser) {
System.out.println("使用系统内短消息的方法,发送消息'"+message+"'给"+toUser);
}
}
[6]邮件短消息的实现类
public class MessageEmail implements MessageImplementor {
@Override
public void send(String message, String toUser) {
System.out.println("使用邮件短消息的方法,发送消息'"+message+"'给"+toUser);
}
}
[7]客户端类
public class Client {
public static void main(String[] args) {
//创建具体的实现对象
MessageImplementor impl = new MessageSMS();
//创建普通消息对象
AbstractMessage message = new CommonMessage(impl);
message.sendMessage("加班申请速批","李总");
//将实现方式切换成邮件,再次发送
impl = new MessageEmail();
//创建加急消息对象
message = new UrgencyMessage(impl);
message.sendMessage("加班申请速批","李总");
}
}
设计模式(7)--Bridge(桥接模式)--结构型的更多相关文章
- Bridge桥接模式(结构型模式)
现有一个需求,一个游戏系统需要构建不同风格的房屋,暂不考虑其他设计模式,需要能实现在PC端.移动端....等等多个平台的构建.最简单的实现方式如下: /// <summary> /// 房 ...
- 设计模式(八):Bridge桥接模式 -- 结构型模式
1. 概述 在软件系统中,某些类型由于自身的逻辑,它具有两个或多个维度的变化,那么如何应对这种“多维度的变化”?如何利用面向对象的技术来使得该类型能够轻松的沿着多个方向进行变化,而又不引入额外的复杂度 ...
- 设计模式(12)--Proxy(代理模式)--结构型
作者QQ:1095737364 QQ群:123300273 欢迎加入! 1.模式定义: 代理模式是对象的结构模式.代理模式给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用. ...
- 设计模式(10)--Facade(外观模式)--结构型
作者QQ:1095737364 QQ群:123300273 欢迎加入! 1.模式定义: 外观模式提供了一个统一的接口,用来访问子系统中的一群接口.外观定义了一个高层接口,让子系统更容易使 ...
- 设计模式(9)--Composite(组合模式)--结构型
1.模式定义: 组合模式属于对象的结构模式,有时又叫做“部分——整体”模式.组合模式将对象组织到树结构中,可以用来描述整体与部分的关系.组合模式可以使客户端将单纯元素与复合元素同等看待. 2.模式特点 ...
- 设计模式07: Bridge 桥接模式(结构型模式)
Bridge 桥接模式(结构型模式) 抽象与实现 抽象不应该依赖于实现细节,实现细节应该依赖于抽象. 抽象B稳定,实现细节b变化 问题在于如果抽象B由于固有的原因,本身并不稳定,也有可能变化,怎么办? ...
- C++设计模式-Bridge桥接模式
作用:将抽象部份与它的实现部份分离,使它们都可以独立地变化. 将抽象(Abstraction)与实现(Implementation)分离,使得二者可以独立地变化. 桥接模式号称设计模式中最难理解的模式 ...
- 一天一个设计模式——Bridge桥接模式
一.概念准备 在理解桥接模式之前,先要理解面向对象程序设计中的两个概念: 类的功能层次结构:假设现在有一个类Something,这个类有一些成员属性和成员方法,但是现有的功能不能满足要求,因此我们想扩 ...
- Bridge桥接模式(设计模式11)
在没有使用桥接模式: 扩展新问题(类归属膨胀问题) 1增加性的电脑类型,要增加每个品牌下面的类 2如果要增加一个新的电脑品牌,要增加美中电脑类型的类 违背单一职责原则: · 一个类:联想笔记本,有两个 ...
随机推荐
- 在Linux环境如何在不解压情况下搜索多个zip包中匹配的字符串内容
今天有个生产文件需要查日志,但因为是比较久远的故障,日志已经被归档为zip包放到某个目录下了,在不知道具体日期时间的情况下,总不能一个一个解压搜索吧.于是就研究一下怎么在多个压缩包里搜索字符串了.目前 ...
- dbgrid数据显示和数据源不同
dbgrid数据显示和数据源不同,在ODBC配置时如下设置,去掉勾
- Oracle批量查询、删除、更新使用BULK COLLECT提高效率
BULK COLLECT(成批聚合类型)和数组集合type类型is table of 表%rowtype index by binary_integer用法笔记 例1: 批量查询项目资金账户号为 &q ...
- Adobe系列软件下载地址
在前些上传的文章中已经讲了如何激活Adobe系列软件,在这放上Adobe系列软件下载地址: 1.Adobe After Effects 2017-14.0 32位下载地址: 链接:http://pan ...
- JavaScript中判断鼠标按键(event.button)
<div id="test"></div> <script> document.oncontextmenu=function(){ return ...
- Java版 QQ空间自动登录无需拷贝cookie一天抓取30WQQ说说数据&流程分析
QQ空间说说抓取难度比较大,花了一个星期才研究清楚! 代码请移步到GitHub GitHub地址:https://github.com/20100507/Qzone [没有加入多线程,希望你可以参与进 ...
- 加减号改变input[type=number]的数值,基于[zepto.js]
通过点击加减号可以更改input的数值,样式如下图: 具体的html代码如下: <div class="xh-lxx-cart-count1"> <span cl ...
- maven-编译速度优化
故障描述: 公司搭建了一个新jenkins持续集成环境,jenkins构建job时间越来越长. 原因分析: 系统CPU限制:判断依据,构建中查看日志 tail -f /var/log/messages ...
- android 7.0 多渠道打包 - 美团开源工具Walle 命令行打包
在Android 7.0(Nougat)推出了新的应用签名方案APK Signature Scheme v2后,之前快速生成渠道包的方式(美团Android自动化之旅-生成渠道包)已经行不通了,对此美 ...
- 【canvas学习笔记一】基本认识
<canvas>标签定义了一块画布,画布可以在网页中绘制2D和3D图象,现在先学习如何绘制2D图象,绘制3D图象属于WebGL的内容(也就是网页版的OpenGL,3D图形接口). 属性 & ...