版权声明:转载必须注明本文转自晓_晨的博客:http://blog.csdn.net/niunai112
目录
导航
设计模式之六大设计原则
设计模式(一)单例模式
设计模式(二)工厂模式
设计模式(三)策略模式
设计模式(四)适配器模式
设计模式(五)享元模式
设计模式(六)建造者模式
设计模式(七)原型模式
设计模式(八)桥接模式
设计模式(九)外观模式
设计模式(十)组合模式
设计模式(十一)装饰器模式
设计模式(十二)代理模式
设计模式(十三)迭代器模式
设计模式(十四)观察者模式
设计模式(十五)中介者模式
设计模式(十六)命令模式
设计模式(十七)状态模式
设计模式(十八)访问者模式
设计模式(十九)责任链模式
设计模式(二十)解释器模式
设计模式(二十一)备忘录模式
设计模式(二十二)模板模式
设计模式总结篇(为什么要学习设计模式,学习设计模式的好处)
前言
LZ带大家来学习一下桥接模式。在项目中经常会用到的模式,我们的JDBC驱动程序也是使用桥接模式,DriverManager中有Driver接口,各个数据库厂商自己实现各自的Driver类,然后在使用的时候,我们只需要把这个Driver放进去就可以了。
桥接模式的目的是:分离抽象化和实现,使两者的接口可以不同,目的是分离。
桥接模式的角色有:
实现(Implementor):定义具体行为,具体特征的应用接口。
具体实现(ConcreteImplementor):实现Implementor。
目标接口(Target): 包含实现具体行为、具体特征的Implementor接口或者类。
桥接模式通过在Target里的操作,调用Implementor得操作,达到了Target的抽象与Implementor实现的分离。
例子
假如LZ是一个组配电脑的,目前只用配电脑的CPU部分,然后帮人装一下系统。那么LZ用JAVA语言怎么写出关系呢?
/***
*
*@Author ChenjunWang
*@Description:操作系统接口
*@Date: Created in 22:17 2018/3/24
*@Modified By:
*
*/
public interface OperationSystem {
void operation();
}
/***
*
*@Author ChenjunWang
*@Description:windows版本实现类
*@Date: Created in 22:19 2018/3/24
*@Modified By:
*
*/
public class WindowsOs implements OperationSystem {
@Override
public void operation() {
System.out.println("This is windows");
}
}
/***
*
*@Author ChenjunWang
*@Description:linux版本实现类
*@Date: Created in 22:19 2018/3/24
*@Modified By:
*
*/
public class LinuxOS implements OperationSystem{
@Override
public void operation() {
System.out.println("This is Linux");
}
}
/***
*
*@Author ChenjunWang
*@Description:i5 linux 电脑
*@Date: Created in 22:24 2018/3/24
*@Modified By:
*
*/
public class I5CPULinuxComputer extends LinuxOS{
public void detail() {
System.out.println("This is i5 cpu");
}
}
/***
*
*@Author ChenjunWang
*@Description:i5 windows 电脑
*@Date: Created in 22:24 2018/3/24
*@Modified By:
*
*/
public class I5CPUWindowsComputer extends WindowsOs{
public void detail() {
System.out.println("This is i5 cpu");
}
}
/***
*
*@Author ChenjunWang
*@Description:i7 linux 电脑
*@Date: Created in 22:22 2018/3/24
*@Modified By:
*
*/
public class I7CPULinuxComputer extends LinuxOS{
public void detail() {
System.out.println("This is i7 cpu");
}
}
/***
*
*@Author ChenjunWang
*@Description:i7 windows 电脑
*@Date: Created in 22:24 2018/3/24
*@Modified By:
*
*/
public class I7CPUWindowsComputer extends WindowsOs{
public void detail() {
System.out.println("This is i7 cpu");
}
}
/***
*
*@Author ChenjunWang
*@Description:客户调用类
*@Date: Created in 22:34 2018/3/24
*@Modified By:
*
*/
public class Client {
public static void main(String[] args) {
System.out.println("客户买 linux i5版本!");
I5CPULinuxComputer i5CPULinuxComputer = new I5CPULinuxComputer();
i5CPULinuxComputer.operation();
i5CPULinuxComputer.detail();
System.out.println("客户买 windows i5版本!");
I5CPUWindowsComputer i5CPUWindowsComputer = new I5CPUWindowsComputer();
i5CPUWindowsComputer.operation();
i5CPUWindowsComputer.detail();
}
}
运行结果如下
--------------------------
客户买 linux i5版本!
This is Linux
This is i5 cpu
客户买 windows i5版本!
This is windows
This is i5 cpu
从上面的例子可以看出,类直接的耦合度太高了,LZ假如要多卖一个操作系统的电脑,那么就要加一个操作系统类,加2个电脑类(i5,i7),LZ在此基础上在加一个i3的型号的电脑,LZ得在加3个类(对应3个操作系统版本)。是不是牵一发动全身的感觉,类越多拓展越费劲。以后修改代码的成本太高,这个时候LZ用桥接模式改造一下。
/***
*
*@Author ChenjunWang
*@Description:操作系统接口
*@Date: Created in 22:17 2018/3/24
*@Modified By:
*
*/
public interface OperationSystem {
void operation();
}
/***
*
*@Author ChenjunWang
*@Description:windows版本实现类
*@Date: Created in 22:19 2018/3/24
*@Modified By:
*
*/
public class WindowsOs implements OperationSystem {
@Override
public void operation() {
System.out.println("This is windows");
}
}
/***
*
*@Author ChenjunWang
*@Description:linux版本实现类
*@Date: Created in 22:19 2018/3/24
*@Modified By:
*
*/
public class LinuxOS implements OperationSystem{
@Override
public void operation() {
System.out.println("This is Linux");
}
}
/***
*
*@Author ChenjunWang
*@Description:电脑抽象类
*@Date: Created in 22:44 2018/3/24
*@Modified By:
*
*/
abstract class Computer {
private OperationSystem OS;
public void setOS(OperationSystem OS){
this.OS = OS;
}
abstract void detail();
public void operation(){
OS.operation();
}
}
/***
*
*@Author ChenjunWang
*@Description:i5实现类
*@Date: Created in 22:57 2018/3/24
*@Modified By:
*
*/
public class I5CPUComputer extends Computer {
public I5CPUComputer(OperationSystem OS) {
setOS(OS);
}
@Override
void detail() {
System.out.println("This is i5 cpu");
}
}
/***
*
*@Author ChenjunWang
*@Description:i7 实现类
*@Date: Created in 22:57 2018/3/24
*@Modified By:
*
*/
public class I7CPUComputer extends Computer {
public I7CPUComputer(OperationSystem OS) {
setOS(OS);
}
@Override
void detail() {
System.out.println("This is i7 cpu");
}
}
/***
*
*@Author ChenjunWang
*@Description:
*@Date: Created in 22:34 2018/3/24
*@Modified By:
*
*/
public class Client {
public static void main(String[] args) {
System.out.println("客户买 linux i5版本!");
I5CPUComputer i5LinuxCPUComputer = new I5CPUComputer(new LinuxOS());
i5LinuxCPUComputer.detail();
i5LinuxCPUComputer.operation();
System.out.println("客户买 windows i5版本!");
I5CPUComputer i5WindowsCPUComputer = new I5CPUComputer(new WindowsOs());
i5WindowsCPUComputer.detail();
i5WindowsCPUComputer.operation();
}
}
运行结果如下
--------------------------
客户买 linux i5版本!
This is i5 cpu
This is Linux
客户买 windows i5版本!
This is i5 cpu
This is windows
现在从整体的代码量上来看,差不懂,但是呢,现在对象之间的耦合度大大减少,当你填加新系统,或者cpu的时候,他们都是互不影响的。如果不解耦,现在的关系只有2层,假如有3层,那么每加一个新的东西,那么要添加的类实在太多了。你想想假如在加一个品牌层,A牌和B牌,不用桥接的模式的话,在加一个C牌,要加的类就是2层的类数乘以第三层的类数,LZ这里就不展开讲了。
总结
优点
(1)分离抽象接口及其实现部分。桥接模式使用“对象间的关联关系”解耦了抽象和实现之间固有的绑定关系,使得抽象和实现可以沿着各自的维度来变化。所谓抽象和实现沿着各自维度的变化,也就是说抽象和实现不再在同一个继承层次结构中,而是“子类化”它们,使它们各自都具有自己的子类,以便任何组合子类,从而获得多维度组合对象。
(2)很多情况下桥接模式可以取代多层继承方案,多层继承方案违背了“单一职责原则”,复用性较差,且类的个数非常多,桥接模式是比多层继承方案更好的解决方法,它极大减少了子类的个数。
(3)由于桥接模式把抽象部分和实现部分分离开了,而且分别定义接口,这就使得抽象部分和实现部分可以分别独立地扩展,而不会相互影响,从而大大地提高了系统的可扩展性。
(4)由于桥接模式把抽象部分和实现部分分离开了,所以在实现桥接的时候,就可以实现动态的选择和使用具体的实现。也就是说一个实现不再是固定的绑定在一个抽象接口上了,可以实现运行期间动态地切换。(LZ的例子是可以自己换操作系统的,用setOS方法)
缺点
(1)桥接模式的使用会增加系统的理解与设计难度,由于关联关系建立在抽象层,要求开发者一开始就针对抽象层进行设计与编程,对开发者对实际项目的理解程度息息相关。
Git地址
本篇实例Github地址:https://github.com/stackisok/Design-Pattern/tree/master/src/bridge
有什么不懂或者不对的地方,欢迎留言。
喜欢LZ文章的小伙伴们,可以关注一波,也可以留言,LZ会回你们的。
觉得写得不错的小伙伴,欢迎转载,但请附上原文地址,谢谢^_^!