七个结构型模式2:桥接模式-Bridge Pattern【学习难度:★★★☆☆,使用频率:★★★☆☆】

问题引入: Sunny软件公司欲开发一个跨平台图像浏览系统,要求该系统能够显示BMP、JPG、GIF、PNG等多种格式的文件,并且能够在Windows、Linux、Unix等多个操作系统上运行。系统首先将各种格式的文件解析为像素矩阵(Matrix),然后将像素矩阵显示在屏幕上,在不同的操作系统中可以调用不同的绘制函数来绘制像素矩阵。系统需具有较好的扩展性以支持新的文件格式和操作系统。

桥接模式是一种很实用的结构型设计模式,如果软件系统中某个类存在两个独立变化的维度,通过该模式可以将这两个维度分离出来,使两者可以独立扩展,让系统更加符合“单一职责原则”。与多层继承方案不同,它将两个独立变化的维度设计为两个独立的继承等级结构,并且在抽象层建立一个抽象关联,该关联关系类似一条连接两个独立继承结构的桥,故名桥接模式。

桥接模式用一种巧妙的方式处理多层继承存在的问题,用抽象关联取代了传统的多层继承,将类之间的静态继承关系转换为动态的对象组合关系,使得系统更加灵活,并易于扩展,同时有效控制了系统中类的个数。桥接定义如下:

桥接模式(Bridge Pattern):将抽象部分与它的实现部分分离,使它们都可以独立地变化。它是一种对象结构型模式,又称为柄体(Handle and Body)模式或接口(Interface)模式。

桥接模式的结构与其名称一样,存在一条连接两个继承等级结构的桥,桥接模式结构如图10-3所示:

这里写图片描述

在桥接模式结构图中包含如下几个角色:

●Abstraction(抽象类):用于定义抽象类的接口,它一般是抽象类而不是接口,其中定义了一个Implementor(实现类接口)类型的对象并可以维护该对象,它与Implementor之间具有关联关系,它既可以包含抽象业务方法,也可以包含具体业务方法。

●RefinedAbstraction(扩充抽象类):扩充由Abstraction定义的接口,通常情况下它不再是抽象类而是具体类,它实现了在Abstraction中声明的抽象业务方法,在RefinedAbstraction中可以调用在Implementor中定义的业务方法。

●Implementor(实现类接口):定义实现类的接口,这个接口不一定要与Abstraction的接口完全一致,事实上这两个接口可以完全不同,一般而言,Implementor接口仅提供基本操作,而Abstraction定义的接口可能会做更多更复杂的操作。Implementor接口对这些基本操作进行了声明,而具体实现交给其子类。通过关联关系,在Abstraction中不仅拥有自己的方法,还可以调用到Implementor中定义的方法,使用关联关系来替代继承关系。

●ConcreteImplementor(具体实现类):具体实现Implementor接口,在不同的ConcreteImplementor中提供基本操作的不同实现,在程序运行时,ConcreteImplementor对象将替换其父类对象,提供给抽象类具体的业务操作方法。

为了减少所需生成的子类数目,实现将操作系统和图像文件格式两个维度分离,使它们可以独立改变,Sunny公司开发人员使用桥接模式来重构跨平台图像浏览系统的设计,其基本结构如图10-5所示:

这里写图片描述

在图10-5中,Image充当抽象类,其子类JPGImage、PNGImage、BMPImage和GIFImage充当扩充抽象类;ImageImp充当实现类接口,其子类WindowsImp、LinuxImp和UnixImp充当具体实现类。完整代码如下所示:

//像素矩阵类:辅助类,各种格式的文件最终都被转化为像素矩阵,不同的操作系统提供不同的方式显示像素矩阵  
class Matrix {  
    //此处代码省略  
}  

//抽象图像类:抽象类  
abstract class Image {  
    protected ImageImp imp;  

    public void setImageImp(ImageImp imp) {  
        this.imp = imp;  
    }   

    public abstract void parseFile(String fileName);  
}  

//抽象操作系统实现类:实现类接口  
interface ImageImp {  
    public void doPaint(Matrix m);  //显示像素矩阵m  
}   

//Windows操作系统实现类:具体实现类  
class WindowsImp implements ImageImp {  
    public void doPaint(Matrix m) {  
        //调用Windows系统的绘制函数绘制像素矩阵  
        System.out.print("在Windows操作系统中显示图像:");  
    }  
}  

//Linux操作系统实现类:具体实现类  
class LinuxImp implements ImageImp {  
    public void doPaint(Matrix m) {  
        //调用Linux系统的绘制函数绘制像素矩阵  
        System.out.print("在Linux操作系统中显示图像:");  
    }  
}  

//Unix操作系统实现类:具体实现类  
class UnixImp implements ImageImp {  
    public void doPaint(Matrix m) {  
        //调用Unix系统的绘制函数绘制像素矩阵  
        System.out.print("在Unix操作系统中显示图像:");  
    }  
}  

//JPG格式图像:扩充抽象类  
class JPGImage extends Image {  
    public void parseFile(String fileName) {  
        //模拟解析JPG文件并获得一个像素矩阵对象m;  
        Matrix m = new Matrix();   
        imp.doPaint(m);  
        System.out.println(fileName + ",格式为JPG。");  
    }  
}  

//PNG格式图像:扩充抽象类  
class PNGImage extends Image {  
    public void parseFile(String fileName) {  
        //模拟解析PNG文件并获得一个像素矩阵对象m;  
        Matrix m = new Matrix();   
        imp.doPaint(m);  
        System.out.println(fileName + ",格式为PNG。");  
    }  
}  

//BMP格式图像:扩充抽象类  
class BMPImage extends Image {  
    public void parseFile(String fileName) {  
        //模拟解析BMP文件并获得一个像素矩阵对象m;  
        Matrix m = new Matrix();   
        imp.doPaint(m);  
        System.out.println(fileName + ",格式为BMP。");  
    }  
}  

//GIF格式图像:扩充抽象类  
class GIFImage extends Image {  
    public void parseFile(String fileName) {  
        //模拟解析GIF文件并获得一个像素矩阵对象m;  
        Matrix m = new Matrix();   
        imp.doPaint(m);  
        System.out.println(fileName + ",格式为GIF。");  
    }  
}  

编写如下客户端测试代码:

class Client {  
    public static void main(String args[]) {  
        Image image;  
        ImageImp imp;  
        image = (Image)XMLUtil.getBean("image");  
        imp = (ImageImp)XMLUtil.getBean("os");  
        image.setImageImp(imp);  
        image.parseFile("小龙女");  
    }  
}  

我的总结:桥接模式通过继承来实现两个维度的扁平化,我自己没用过,值得学习,可以参考这个例子图片桥接

参考链接:
桥接模式

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值