主文章(所有java设计模式的目录) |
---|
https://blog.csdn.net/grd_java/article/details/122252696 |
源码位置 |
---|
码云:https://gitee.com/yin_zhipeng/design_mode.git |
GitHub: |
学习设计模式前必须知道的东西 |
---|
看待设计模式,要站在更大的角度(代码重用性、可读性、可扩展性、可靠性、程序高内聚,低耦合)来综合考虑看待,而不是功能实现的角度看待,不要觉得实现一个功能没必要这么麻烦
文章中给出的设计模式类图都是标准的实现方式,并不一定要完全遵守标准,所以只要设计思想符合,一个设计模式有多种实现方式,尤其是看别人源码的时候,不要用标准类图死扣
1. 桥接模式(Bridge Pattern)
手机操作问题,了解类爆炸,以下设计方式,违反单一职责原则 |
---|
- 对于不同手机类型,不同品牌实现操作编程(开机,关机,打电话等)
- 假设加上一个种类,翻盖式,那么我们就需要再创建一个翻盖式抽象,实现3个品牌
- 一个两个还好,如果添加100个种类呢?就会发生类爆炸(类贼多)
- 上图中,
HuaWei类、Vivo类、XiaoMi类,每个手机种类都有3个,有100个种类就需要100个
我们要保证,就算我们有1000个种类,也只需要各种类,1个,而不是1000个
桥接模式 |
---|
- 将实现与抽象放在两个不同类层次中,使两个层次可以独立改变
- 一种结构型设计模式
- 基于类的最小设计原则,通过使用封装,聚合和继承等行为让不同的类承担不同的职责。主要特点是把抽象(Abstraction)与行为实现(Implementation)分离开来,从而可以保持各部分的独立性以及应对他们的功能扩展
通俗理解
:手机都有个种类,但是每个品牌的手机都需要彰显自己的与众不同,例如翻盖手机,都能翻盖,但是小米手机是上下翻盖,Vivo手机是左右翻盖,所以具体功能的实现是每个品牌厂商自己实现的,所以我们实际动作,比如打电话,是Vivo或XiaoMi类实际操手的,其它类都只做一些抽象和无关功能的实现
类图:com/yzpnb/design_mode/bridge_pattern/uml/bridge_pattern.puml |
---|
1. 利用桥接模式,解决手机操作的类爆炸问题
类图:com/yzpnb/design_mode/bridge_pattern/uml/Phone.puml |
---|
- 桥怎么回事呢?
FoldedPhone的call()
方法,除了自己的个性实现,还调用了Phone类的call()
方法Phone类的call()
方法,实际调用的是Brand接口的call()
方法- 接口
Brand的call()
是个抽象,实际调用
工作的,是Vivo和XiaoMi等类的call()
方法- 这样就
像一个桥一样,所以叫桥接模式
- 明显的改观就是,
尽管我们有两个种类,Vivo和XiaoMi品牌也都只有一个,就算增加100个种类,品牌个数也不会变
代码:com/yzpnb/design_mode/bridge_pattern/phone |
---|
- 品牌抽象(行为实现类接口)
- 品牌实现类(行为具体实现类)
- 种类,维护品牌(组合),就算各品牌,要按照种类生产手机(维护行为实现类接口)
- 翻盖种类,行为的具体实现类
- 用户用的时候,觉得是通过翻盖手机打电话,但实际,打电话功能是厂商自己实现的(苹果和安卓手机,都是触碰手机,但是打电话界面是不一样的)
2. 源码中用到的桥接模式
JDBC的Driver接口(从桥接模式看),这就是一个接口,而MySql和Oracle都有Driver类,我们不能因为种类不一样,而每一个种类都写一套实现,所以这里使用了桥接模式 |
---|
- 这里的桥接设计模式,和我们上面介绍的标准的实现方式不一样,但是思想对了就行,毕竟java设计模式标准的制定是在java出现很久之后才规定出来的
- 先看com.mysql.cj.jdbc.Driver,这是Mysql的驱动类
- 进入DriverManager观看,getConnection方法,看他获取的是什么Connection对象
- 看看Connection是什么,原来就是一个接口,它下面,是mysql实现的,如果我们引入Oracle的JDBC依赖,你还会看见Oracle的,我们进入ConnectionImpl类看看
- 5.0版本JDBC的类图如下