当前位置:   article > 正文

设计模式之(七)桥接模式_若不采 用桥接模式,而是采用多层继承方案(图片格式为父类,操作系统为子类) 则要设

若不采 用桥接模式,而是采用多层继承方案(图片格式为父类,操作系统为子类) 则要设

桥接模式

概述

将抽象部分与其实现部分分离,使他们可以独立的变化,是一种对象型结构模式,又被称为柄体模式或者接口模式。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
上述设计存在如下问题

  1. 采用多层继承的结构,导致系统中的类极具增加,没加一个图片格式都要增加4个类。
  2. 系统扩展麻烦,无论是增加图片格式还是操作系统,都需要增加大量的类。
  3. 具体的实现类违背了单一职责,不仅要实现不同系统的矩阵显示还要进行图片格式的解析。

介入桥接模式

维度分离:通过系统分析我们可以得到两种维度,不同系统的显示和图片格式的解析。
桥接模式正好解决了这个问题,是两个不同的维度可以独立的扩展,用一种巧妙的处理了多层继承的问题,它将两个独立变化的维度设计为两个独立的继承等级结构,并且在抽象层建立一个抽象关联,这个关联关系类似一条连接两个独立继承结构的桥,故名为桥接模式
在这里插入图片描述
在这里插入图片描述
(1)Abstraction(抽象类)用于定义抽象类的接口,一般是抽象类而不是接口,其中定义了一个(Implementor)实现类接口类型对象,并且可以维护他。这就是桥接模式的巧妙之处
(2)RedinedAbstraction(扩充抽象类)扩充由Abstraction定义的接口,通常情况下不是抽象类而是具体类,实现了抽象类的业务方法,在RedinedAbstraction中可以调用Implementor中定义的方法。
(3)Implementor(实现类接口)提供业务的基本操作,具体实现交给ConcreteImplementor(具体实现类接口),通过关联关系,Abstraction不仅有自己的方法,而可以嗲用Implementor中定义的方法,使用关联关系来替代继承关系。
(4)ConcreteImplementor(具体实现类接口)实现Implementor接口不同的业务实现,利用里氏替换原则,具体实现类取代其父类对象,提供具体业务的实现方法。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

package com.learn.designmode.mode.birdge.baseimage;

import com.learn.designmode.mode.birdge.imageImpl.ImageImp;

public abstract class BaseImage {

    // 声明实现类接口
    protected ImageImp imageImp;

    // 通过注入的方法
    public void setImageImp(ImageImp imageImp){
        this.imageImp = imageImp;
    }
    // 声明抽象业务方法
    public abstract void parseFile(String fileName);
}


  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
package com.learn.designmode.mode.birdge.baseimage;

import com.learn.designmode.mode.birdge.Matrix;
import com.learn.designmode.mode.birdge.baseimage.BaseImage;

public class GIFImage extends BaseImage {

    @Override
    public void parseFile(String fileName) {
        imageImp.doPaint(new Matrix());
        System.out.println(fileName +",格式为GIF");
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
package com.learn.designmode.mode.birdge.baseimage;

import com.learn.designmode.mode.birdge.Matrix;
import com.learn.designmode.mode.birdge.baseimage.BaseImage;

public class PNGImage extends BaseImage {

    @Override
    public void parseFile(String fileName) {
        imageImp.doPaint(new Matrix());
        System.out.println(fileName +",格式为PNG");
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
package com.learn.designmode.mode.birdge.imageImpl;

import com.learn.designmode.mode.birdge.Matrix;

public interface ImageImp {

    /** 抽象业务方法
     * @param matrix
     */
    void doPaint(Matrix matrix);
}


  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
package com.learn.designmode.mode.birdge.imageImpl;

import com.learn.designmode.mode.birdge.Matrix;
import com.learn.designmode.mode.birdge.imageImpl.ImageImp;

public class LinuxImageImp implements ImageImp {

    @Override
    public void doPaint(Matrix matrix) {
        System.out.println("在LinuxImageImp显示图像");
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
package com.learn.designmode.mode.birdge.imageImpl;

import com.learn.designmode.mode.birdge.Matrix;
import com.learn.designmode.mode.birdge.imageImpl.ImageImp;

public class UnixImageImp implements ImageImp {

    @Override
    public void doPaint(Matrix matrix) {
        System.out.println("在UnixImageImp显示图像");
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
package com.learn.designmode.mode.birdge.imageImpl;

import com.learn.designmode.mode.birdge.Matrix;
import com.learn.designmode.mode.birdge.imageImpl.ImageImp;

public class WindowsImageImp implements ImageImp {

    @Override
    public void doPaint(Matrix matrix) {
        System.out.println("在Windows显示图像");
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
package com.learn.designmode.mode.birdge;

import com.learn.designmode.mode.birdge.baseimage.BaseImage;
import com.learn.designmode.mode.birdge.imageImpl.ImageImp;
import com.learn.designmode.mode.factory.chart.utils.XMLUtil;
import org.xml.sax.SAXException;

import javax.xml.parsers.ParserConfigurationException;

import java.io.IOException;

public class Client {
    public static void main(String[] args) throws SAXException, IllegalAccessException, IOException, InstantiationException, ParserConfigurationException, ClassNotFoundException {
        ImageImp imageImp = (ImageImp) XMLUtil.getBean("ImageImplclassName");
        BaseImage image = (BaseImage) XMLUtil.getBean("ImageclassName");
        image.setImageImp(imageImp);
        image.parseFile("小龙女");
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
package com.learn.designmode.mode.birdge;

public class Matrix {
}

  • 1
  • 2
  • 3
  • 4
  • 5

如果需要扩展图片格式或者操作系统显示,只需要增加一个对应的扩充抽象类或者具体的实现类,具有很好的扩展性。

适配器模式和桥接模式的联用

在这里插入图片描述
在这里插入图片描述

总结

桥接模式是Java虚拟机和实现JDBC等驱动程序的核心模式之一,应用较为广泛,软件开发过程中,如果一个类或者系统有个变化的维度时,都可以尝试采用桥接模式对其进行设计,可以降低系统的复杂度。

主要优点

(1)分离抽象接口及其实现部分,桥接模式采用对象间的关联关系解耦抽象与实现之间固有的绑定关系,使得抽象和实现可以沿着自己的维度变化来变化,抽象化基本操作,子类化维度变化,以便任意组合的子类,从而获得多维度组合对象。
(2)桥接模式可以取代多层继承方案,继承方案违背了单一职责,复用性差,采用桥接模式可以极大的减少子类的个数。
(3)符合开闭原则,如果维度需要扩招,增加新的具体实现类就行。

主要缺点

(1)桥接模式往往是在抽象层建立关联关系,要求开发者一开始就针对抽象层进行编程与设计。
(2)桥接模式需要识别出系统的不同维度,这对开发经验有重要因素,使用范围具有一定的局限性。

适用场景

(1)如果一个在抽象类和具体类之间增加更多的灵活性,避免两个层次之间建立静态的继承关系,通过桥接模式可以在抽象层建立一个关联关系。
(2)抽象部分和实现部分可以以继承的方式进行扩展而又互不影响,在程序运行的时候可以动态的将一个抽象类和实现类接口的子类进行组合,实现动态解耦
(3)一个类存在两个或者多个独立变化的维度,这两个维度都可以独立进行扩展。
(4)对于那些不希望使用多继承或者因多层继承结构导致系统类的个数极具的增加,桥接模式尤为使用。
在这里插入图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/凡人多烦事01/article/detail/569072
推荐阅读
相关标签
  

闽ICP备14008679号