引言

在实际的业务中,经常会遇到多维度的概念组合,公园的门票,颐和园有年票、月票、日票,故宫也有年票、月票、日票。那么不同的公园票种类型就可以视为两种不同的纬度,它们之间会形成相互组合的关系。

在类的设计上,如果任由两种纬度的类任意组合的话,那么就会形成笛卡尔积的情况,使类泛滥,难以维护。

在设计模式中,桥接模式就是为了解决这个问题而提出的,它通过将两种或多种纬度以上层抽象的组合关系为基础,形成一种桥接模型,将业务的组合时机延迟到客户端调用使才发生,避免在编写类的时候,大量的枚举每一种具体情况。

一、待解决问题描述

类似上面公园和票种的纬度关系,这里提出一种简单的案例:形状和颜色。

假设我们需要两种不同的形状——圆形、正方形,和两种不同的颜色——红色、白色,并将它们组合以产生特定的类型,那么我们就需要四种不同:

这种做法虽然简单直观,但也大大增加了类的数量,而且两个维度的概念耦合性太强,如果增加了新的纬度,那么类的规模将成倍增长。

二、桥接模式类图

在学习桥接模式的时候,不仅应该掌握最主要的纬度的划分与如何实现桥接,还应该思考桥接模式之外的内容,比如上面的例子中,我们可以很清晰的划分出形状颜色两个维度,同时下面的类图也展示了通过怎样的编码技巧实现桥接的解耦。还有一点之外的内容就是,我们应该以哪种维度作为主干?为什么接入主干维度的其他维度要采用接口?而主干维度采用抽象类?

上图中,Shape是一个抽象类,这是对主干维度——形状的一个抽象,其实现类有Circle、Square,它们代表了一种具体的形状。

Color是一个接口,Red、White代表两种不同的具体的颜色。

在这个例子中,Color 和 Shape 相比,很显然Shape更像是一种主体纬度,而颜色,更适合作为一种附属属性依附于主体纬度,在这个例子中 Color 仅仅提供了一种行为,所以直接使用接口来描述,这当然不是必须的。

Color 与 Shape 的关系是聚合,采用的是 set 方法注入到 Shape 中,这需要根据具体的业务来判断两种纬度的依赖关系,聚合的耦合度更低,且更灵活,可以只在必要的时候将两种纬度聚合在一起。而组合可能在构造时就需要传入属性,这需要视具体情况而定。

三、桥接模式的具体实现

/*** 主干维度————形状*/
public abstract class Shape {protected Color color;public void setColor(Color color) {this.color = color;}public abstract void draw();
}
/*** 颜色维度*/
public interface Color {void paint(String shape);
}
public class Circle extends Shape {@Overridepublic void draw() {color.paint("圆形");}
}
public class Square extends Shape {@Overridepublic void draw() {color.paint("正方形");}
}
public class Red implements Color {@Overridepublic void paint(String shape) {System.out.println("红色的" + shape);}
}
public class White implements Color {@Overridepublic void paint(String shape) {System.out.println("白色的" + shape);}
}

以上是桥接模式中的几个重要角色,以下是测试代码:

public class Client {public static void main(String[] args) {Shape square = new Square();square.setColor(new Red());square.draw();square.setColor(new White());square.draw();System.out.println("==============");Shape circle = new Circle();circle.setColor(new Red());circle.draw();circle.setColor(new White());circle.draw();}
}

输出结果:

红色的正方形
白色的正方形
==============
红色的圆形
白色的圆形

总结

桥接模式基于类的最小设计原则,其中包括几个重要的角色:

1、Client,客户端

2、Abstraction,抽象类

3、Refined Abstraction ,扩展抽象类

4、Implementor,行为实现类接口

5、ConcreteImplementor, 具体的行为实现

桥接模式标准类图如下:

桥接模式有以下几点好处:

1、实现了抽象与行为的分离

2、更好的扩展性

3、可动态切换实现

4、实现细节对客户端透明,可以对用户隐藏实现细节

缺点也有几点:

1、增加了系统的理解难度和设计难度,由于聚合关联关系建立在抽象层,要求开发者针对抽象进行设计和编程。

2、桥接模式要求正确识别出系统中的两个独立变化的纬度,因此使用范围具有一定的局限性。

Java常用设计模式————桥接模式相关推荐

  1. Java常用设计模式————原型模式(一)

    介绍 原型模式(Prototype Pattern):用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象. 原型模式用于创建重复的对象,同时又能保证性能.当直接创建对象的代价比较大时,则采用 ...

  2. Java常用设计模式————工厂模式

    简介: 工厂模式(Factory Pattern)是Java中最常用的设计模式之一,又称多态工厂模式.虚拟构造器模式.属于创建型模式. 在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通 ...

  3. Java常用设计模式————组合模式

    引言 组合模式,是一种类似递归算法的结构性设计模式,通过以简单的 List ,组合本类对象,实现树状对象结构的"部分.整体"的层次. 它可以让调用程序不需要关心复杂对象与简单对象的 ...

  4. Java常用设计模式-策略模式

    策略模式是一个非常实用的设计模式,指定义了一类算法并将其封装起来,并使得它们之间可以灵活地切换,并且不影响客户端. 1,从一个例子开始 我们常常会在网上买东西,很多购物平台都会有着各种各样的优惠策略供 ...

  5. Java 常用设计模式 -- Builder模式

    Builder模式是在Java中最流行的模式之一.它很简单,有助于保持对象不可变,并且可以使用Project Lombok的@Builder或Immutables等工具生成,仅举几例. 模式的流畅变体 ...

  6. Java常用设计模式————建造者模式

    引言 建造者模式(Builder Pattern)使用多个简单对象一步一步构建成一个复杂的对象.这种类型的设计模式属于建造型模式,它提供了一种创建对象的最佳方式. 一个Builder会一步步构建最终的 ...

  7. Java常用设计模式————外观模式

    引言 外观模式(Facade Pattern),又叫"过程模式".外观模式为子系统中的一组接口提供一个一致的入口,此模式定义了一个高层接口,这个接口使得这一组子系统更加易用. 一. ...

  8. Java常用设计模式————原型模式(二)之深拷贝与浅拷贝

    引言 clone顾名思义就是复制, 在Java语言中, clone方法被对象调用,所以会复制对象.所谓的复制对象,首先要分配一个和源对象同样大小的空间,在这个空间中创建一个新的对象.那么在java语言 ...

  9. 初学Java常用设计模式之——装饰器模式

    声明:转载请附上原文链接 提示:标题序号从8开始,是照应不同设计模式笔记发布的顺序而定的,比如,上一篇文章 初学Java常用设计模式之--桥接模式和组合模式 序号从7开始. 8. 装饰器设计模式(重点 ...

最新文章

  1. mysql和mongodb配合_MongoDB和Mysql怎样结合
  2. 想写点什么留下点念想
  3. 学习笔记----周志华《机器学习》第五章(神经网络)(二)
  4. 分布式ID-雪花算法
  5. Spring MVC 中使用AOP 进行事务管理--XML配置实现
  6. 读书笔记-互联网思维必读10本书之一《免费》
  7. DEEPIN教程 - 本地安装Typora
  8. 你的adonis用对了吗?不同因素的顺序竟然对结果有很大影响
  9. 思维导图 源码 php,使用思维导图,优雅的完成自己的代码
  10. Linux命令(20)linux服务器之间复制文件和目录
  11. 华三服务器如何修改默认ip,H3C路由器默认登录入口 192.168.124.1 设置步骤
  12. FC-SAN存储技术
  13. C++ 输入输出(cin cout)加速/效率优化
  14. win10取消登录密码
  15. 多功能智能台灯(附源码)——用于参加课程设计,电子竞赛等
  16. 行驶证识别/行驶证OCR识别全方位解析
  17. Notes of Python Cookbook (Chr1-Chr3)
  18. Unit 和 Int转换 Unit转Int Int转Unit
  19. 75.android 简单的获取当前可用运行内存,总运行内存,获取包含系统软件在内的所有内存,获取系统参数显示的内存大小。
  20. 全新UI简洁H5商城网站源码/带易支付接口

热门文章

  1. array.unshift_Ruby中带有示例的Array.unshift()方法
  2. Promethus搭建 K8S 集群节点资源监控系统
  3. latex目录标题中间空一个字符
  4. 技校计算机英语,技校计算机英语的一体化教学
  5. python 默认配置文件_python各类配置文件写法
  6. dw如何写php代码提示,DW CS5 jquery代码提示插件
  7. springboot导包显示不存在_基础篇:Spring Boot入门体验(图文教程)
  8. Windows11电脑锁屏快捷键是什么
  9. win7系统显卡在哪查看
  10. 谷歌Chrome浏览器发布10年成霸主