设计模式(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如果要增加一个新的电脑品牌,要增加美中电脑类型的类 违背单一职责原则: · 一个类:联想笔记本,有两个 ...
随机推荐
- Java 容器在实际项目中的应用
前言:在java开发中我们离不开集合数组等,在java中有个专有名词:"容器" ,下面会结合Thinking in Java的知识和实际开发中业务场景讲述一下容器在Web项目中的用 ...
- Linux - 请允许我静静地后台运行
h1,h2,h3,h4,h5,h6,p,blockquote { margin: 0; padding: 0 } body { font-family: "Helvetica Neue&qu ...
- 关于 Eclipse中的Web项目 部署的文件位置 查看jsp源码的部署位置
使用 eclipse 开发web项目 会默认 部署在 工作目录下: .metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps 在这里 ...
- 关于Win7 内存变小处理方法
windows + R 输入msconfig 点击引导 点击高级选项 点击最大内存打钩,就好了,你重启,你的内存将恢复成原来的.
- 使用curl,libcurl访问Https
编译curl,libcurl 下载curl源码(git clone https://github.com/curl/curl),在目录curl\winbuild\BUILD.WINDOWS.txt文件 ...
- nodejs之querystring模块
这里主要记下querystring模块的使用方法. querystring从字面上的意思就是查询字符串,一般是对http请求所带的数据进行解析.querystring模块只提供4个方法,在我看来,这4 ...
- 关于table表格td里内容是数字而且太长不换行的问题
<p>table{table-layout:fixed}</p><p>table td{word-wrap:break-word}</p><p&g ...
- 2017年7月Web服务器调查报告
在2017年7月的调查中,我们收到了来自1,767,964,429个网站和6,593,508个面向web的计算机的反馈.这是一个小小的进步,网站的数量增加了100万个(+0.06%),面向web的计算 ...
- (转)java.util.Scanner应用详解
java.util.Scanner应用详解 java.util.Scanner是Java5的新特征,主要功能是简化文本扫描.这个类最实用的地方表现在获取控制台输入,其他的功能都很鸡肋,尽管Java ...
- iOS 使用 socket 即时通信(非第三方库)
其实写这个socket一开始我是拒绝的. 因为大家学C 语言和linux基础时肯定都有接触,客户端和服务端的通信也都了解过,加上现在很多开放的第三方库都不需要我们来操作底层的通信. 但是来了!!! 但 ...