桥接模式
概述
桥接模式是一种很适用的结构型设计模式,如果系统中的某个类存在两个独立变化的维度,通过桥接模式可以将这两个维度分离出来,使得两者可以独立拓展
蜡笔 : 颜色和大小型号 存在较强和耦合性
毛笔: 颜色和大小型号,就是两个不同的维度,
桥接模式: 将抽象部分与它实现部分解耦,使得两个能够独立变化
桥接模式
- Abstracton(抽象类) 它是用于定义抽象类的接口,通常是抽象类而不是接口,其中定义了一个Implementor(实现类接口)类型的对象并可以维护该对象,它与Implementor之间具有关联关系,它即可以包含抽象业务方法,也可以包含具体业务方法
- RefinedAbstraction(扩充抽象类) 它扩充有Abstraction 定义的接口,通常情况下它不再是抽象类而是具体类,实现了Abstraction 中声明的抽象业务方法,再RefinedAbstraction 中可以调用再Implementor中定义的业务犯法
- Implementor(实现类接口) 定义实现的接口,这个接口不一定要与Abstraction的接口完全一直,事实上这两个接口可以完全相同
- ConcreteImplementor(具体实现类) 具体实现了Implementor接口,再不同ConcreteImplementor中提供基本操作的不同实现,在程序运行时ConcreteImplementor对象将替换其父类对象,提供给抽类具体的业务操作方法
/**
* @ClassName: ImageImpl
* @Description: 抽象操作系统的实现方法,充当实现类接口
* @Author Crazy
* @DateTime 2019年11月2日 下午9:54:23
*/
public interface ImageImp {
public void doPaint(Matrix m); //
}
public class LinuxImp implements ImageImp {
@Override
public void doPaint(Matrix m) {
//调用linux系统的绘制函数 绘制像素矩阵
System.out.println("在linux操作系统中显示图片");
}
}
public class UnixImp implements ImageImp {
@Override
public void doPaint(Matrix m) {
// TODO Auto-generated method stub
//调用Unix系统的绘制函数 绘制像素矩阵
System.out.println("在Unix操作系统中显示图片");
}
}
public class WindowsImp implements ImageImp {
@Override
public void doPaint(Matrix m) {
//调用windows系统的绘制函数 绘制像素矩阵
System.out.println("在windows操作系统中显示图片");
}
}
/**
* @ClassName: Image
* @Description: 抽象图像类,充当抽象类
* @Author Crazy
* @DateTime 2019年11月2日 下午10:00:22
*/
public abstract class Image {
protected ImageImp imp ;
//注入实现类接口对象
public void setImageImp(ImageImp imp) {
this.imp = imp;
}
public abstract void parseFile(String fileName);
}
public class BMPImage extends Image {
@Override
public void parseFile(String fileName) {
// 模拟解析jpg 文件获得像素矩阵对象m
Matrix m = new Matrix();
imp.doPaint(m);
System.out.println(fileName + "格式为 BMP");
}
}
public class GIFImage extends Image {
@Override
public void parseFile(String fileName) {
// 模拟解析jpg 文件获得像素矩阵对象m
Matrix m = new Matrix();
imp.doPaint(m);
System.out.println(fileName + "格式为 GIF");
}
}
public class JPGImage extends Image {
@Override
public void parseFile(String fileName) {
// 模拟解析jpg 文件获得像素矩阵对象m
Matrix m = new Matrix();
imp.doPaint(m);
System.out.println(fileName + "格式为 jpg");
}
}
public class Client {
public static void main(String[] args) {
// TODO Auto-generated method stub
Image image ;
ImageImp imp ;
image = new JPGImage();
imp = new WindowsImp();
image.setImageImp(imp);
image.parseFile("小龙女");
image = new GIFImage();
imp = new UnixImp();
image.setImageImp(imp);
image.parseFile("yang");
}
}
桥接模式与适配器模式的联用
适配器模式可以解决两个已有接口间不兼容的问题,在这中情况下被适配的类往往时一个黑盒子,有时候不想也不能改变这个被适配的类,也不能控制器扩展
适配器模式通常用于现有系统与第三方产品功能的集成,采用增加适配器的方式将第三方类集成到系统中,
桥接模式则不同,用户可以通过接口集成或类集成的方式对系统进行扩展
桥接模式用于系统初步设计,对于存在两个独立变化维度的类可以将其分为抽象化和实现化两个不同角色,他们可以分别进行变化,而初步设计完成后,当发现系统与育有类无法协同工作时采用适配器模式
优缺点
桥接模式时设计java虚拟机和实现JDBC等驱动程序的核心模式之一,应用较为广泛,
优点:
- 分离抽象接口机器实现部分,桥接模式适用"对象间的关联关系"解耦了抽象和实现之间固有的绑定关系,使得抽象和实现可以沿着各自的维度来变化,
- 桥接模式取代了多层继承方案,多层继承方案违背了单一职责原则,复用性差,并且类的个数非常多,桥接模式时比多层继承方案更好的解决方法,它极大的减少了子类的个数
- 桥接模式提高了系统的可扩展性,在两个变化维度中任意扩展一个维度都不需要修改原有系统, 符合开闭原则
缺点:
- 桥接模式的适用会增加系统的理解和设计难度,由于关联关系建立在抽象层,要求开发者一开始就针对抽象层进行设计与编程
- 桥接模式要求正确的识别出系统中两个独立变化的维度,因此其适用范围具有一定的局限性,
适用环境
- 如果一个系统需要在抽象化和具体化之间增加更多的灵活性,避免在两个层次之间建立静态继承关系,通过桥接模式可以使他们在抽象层建立一个关联关系
- 抽象部分和实现部分可以用继承的方式独立扩展而互不影响,在程序运行时可以动态的将一个抽象化子类的对象和一个实现化子类的对象进行组合,即系统需要对抽象化角色和实现化角色进行动态耦合
- 一个类存在两个或多个独立变化的维度且这两个或多个维度都需要独立进行扩展
- 对于那些不希望使用继承或因多层继承导致系统类的个数急剧增加的系统,桥接模式尤为适用