设计模式(八)桥接模式

版权声明:转载必须注明本文转自晓_晨的博客: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会回你们的。
觉得写得不错的小伙伴,欢迎转载,但请附上原文地址,谢谢^_^!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章