【设计模式】通过简单案例学习桥接模式

「这是我参与11月更文挑战的第2天,活动详情查看:2021最后一次更文挑战

桥接模式

  桥接(Bridge)是用于把抽象化与实现化解耦,使得二者可以独立变化。这种类型的设计模式属于结构型模式,它通过提供抽象化和实现化之间的桥接结构,来实现二者的解耦。

  在有多种可能会变化的情况下,用继承会造成类很多,扩展起来不灵活,因此使用桥接模式将抽象部分与实现部分分离,使它们都可以独立的变化。
桥接模式优点:

  • 1、抽象和实现的分离。
  • 2、优秀的扩展能力。
  • 3、实现细节对客户透明。

  下面结合案例进行简单的介绍。

案例分析

  本次采用的是比较经典的大家都熟悉的案例,是某年软件设计师的试题。具体如下:

  现欲实现一个图像浏览系统,要求该系统能够显示BMP、JPEG和GIF三种格式的文件,并且能够在 Windows和 Linux两种操作系统上运行。系统首先将BMP、JPEG和GIF三种格式的文件解析为像素矩阵,然后将像素矩阵显示在屏幕上。系统需具有较好的扩展性以支持新的文件格式和操作系统。为满足上述需求并减少所需生成的子类数目,采用桥接( Bridge设计模式进行设计,所得类图如下图所示。
图片.png

  通过题干分析可以知道需要读取的文件格式可能是多种的,而且可能在不同的操作系统中去展示图像,而需要将文件的展示与系统的实现集合起来。经过分析,文件的格式可能是多种多样的,操作系统也是多种多样的,因此使用桥接模式对该题设计比较好。
下面开始进行简单代码实现。下图是建好的文件。
图片.png

编写图像展示抽象类

编写图像展示抽象类,是为了在后期,新加入不同的操作系统之后,只需要集成此抽象类,就可以快速实现不同类型文件的图像展示。使图像文件类型与操作系统之间进行解耦。
编写代码如下,只有一个图像输出的方法。

/**
 * @ClassName ImageHandler
 * @Description:
 * @Author 公众号:Java全栈架构师
 * @Version V1.0
 **/
public abstract class ImageHandler {
    public abstract void doPaint(PictureElement pe);
}

复制代码

其中PictureElement 是展示的图像像素点,由于是模拟展示,本次针对此对象只显示文件名称。

/**
 * @ClassName PictureElement
 * @Description:
 * @Author 公众号:Java全栈架构师
 * @Version V1.0
 **/
public class PictureElement {
    private String fileName;

    public String getFileName() {
        return fileName;
    }

    public PictureElement(String fileName) {
        this.fileName = fileName;
    }

    public void setFileName(String fileName) {
        this.fileName = fileName;
    }
}

复制代码

Linux系统展示

/**
 * @ClassName LinuxImageImpl
 * @Description:
 * @Author 公众号:Java全栈架构师
 * @Version V1.0
 **/
public class LinuxImageImpl extends ImageHandler {
    @Override
    public void doPaint(PictureElement pe) {
        System.out.println("Linux 输出图像。文件名称是:" + pe.getFileName());
    }
}
复制代码

Windows系统展示

/**
 * @ClassName WinImageImpl
 * @Description:
 * @Author 公众号:Java全栈架构师
 * @Version V1.0
 **/
public class WinImageImpl extends ImageHandler {
    @Override
    public void doPaint(PictureElement pe) {
        System.out.println("Windows 输出图像。文件名称是:" + pe.getFileName());
    }
}
复制代码

编写图像文件处理类

创建一个抽象ImageInfo的类,其中包含图像显示类和图像文件转换类两个。

/**
 * @ClassName ImageInfo
 * @Description:
 * @Author 公众号:Java全栈架构师
 * @Version V1.0
 **/
public abstract class ImageInfo {
    protected ImageHandler imageHandler;

    public void setImageHandler(ImageHandler image) {
        this.imageHandler = image;
    }

    public abstract void parseFile(String fileName);
}
复制代码

编写不同文件处理方法

JPEG文件处理。

/**
 * @ClassName JPEG
 * @Description:
 * @Author 公众号:Java全栈架构师
 * @Version V1.0
 **/
public class JPEG extends ImageInfo {
    @Override
    public void parseFile(String fileName) {
        System.out.println("将JPEG格式文件转成图像像素矩阵对象");
        PictureElement pe = new PictureElement(fileName);
        imageHandler.doPaint(pe);
    }
}
复制代码

GIF文件处理。

/**
 * @ClassName GIF
 * @Description:
 * @Author 公众号:Java全栈架构师
 * @Version V1.0
 **/
public class GIF extends ImageInfo {
    @Override
    public void parseFile(String fileName) {
        System.out.println("将GIF格式文件转成图像像素矩阵对象");
        PictureElement pe = new PictureElement(fileName);
        imageHandler.doPaint(pe);
    }
}
复制代码

BMP文件处理。

/**
 * @ClassName BMP
 * @Description:
 * @Author 公众号:Java全栈架构师
 * @Version V1.0
 **/
public class BMP extends ImageInfo {
    @Override
    public void parseFile(String fileName) {
        System.out.println("将BMP格式文件转成图像像素矩阵对象");
        PictureElement pe = new PictureElement(fileName);
        imageHandler.doPaint(pe);
    }
}
复制代码

运行

通过main运行一下简单的测试类可以看到运行结果如下。

/**
 * @ClassName MainApplication
 * @Description:
 * @Author 公众号:Java全栈架构师
 * @Version V1.0
 **/
public class MainApplication {
    public static void main(String[] args) {
        //在 Linux 查看GIF图片
        ImageInfo imageInfoGIF = new GIF();
        LinuxImageImpl linuxImage = new LinuxImageImpl();
        imageInfoGIF.setImageHandler(linuxImage);
        imageInfoGIF.parseFile("test.GIF");

        //在 Windows 查看JPEG图片
        ImageInfo imageInfoJPEG = new JPEG();
        WinImageImpl winImage = new WinImageImpl();
        imageInfoJPEG.setImageHandler(winImage);
        imageInfoJPEG.parseFile("test.JPEG");



    }
}



复制代码

运行结果:

将GIF格式文件转成图像像素矩阵对象
Linux 输出图像。文件名称是:test.GIF
将JPEG格式文件转成图像像素矩阵对象
Windows 输出图像。文件名称是:test.JPEG
复制代码

图片.png

  好了,一个简单的桥接模式就介绍完成了,学习设计模式的时候,尽量结合熟悉的案例进行分析,这样的话就会有事半功倍的奇效,也更容易理解。大家可以尝试着在项目中使用设计模式的方式进行开发。

  感谢您的阅读,希望您喜欢,如对您有帮助,欢迎点赞收藏。如有不足之处,欢迎评论指正。下次见。

  作者介绍:【小阿杰】一个爱鼓捣的程序猿,JAVA开发者和爱好者。公众号【Java全栈架构师】维护者,欢迎关注阅读交流。