1.意图:将抽象部分与其实现部分分离,使它们都可以独立地变化。
2.结构
Abstraction定义抽象类的接口,维护一个指向Implementor类型对象的指针;
RefinedAbstraction扩充由Abstraction定义的接口;
Implementor定义实现类的接口,该接口不一定要与Abstraction的接口完全一直;事实上这两个接口可以完全不同。一般来说,Implementor接口仅提供基本操作,而Abstraction定义了基于这些基本操作的较高层次的操作;
ConcreteImplementor实现Implementor接口并定义它的具体实现。
3.适用性:
不希望在抽象和它的实现部分之间有一个固定的绑定关系。例如,这种情况可能是因为,在程序运行时刻实现部分应可以被选择或者切换;
类的抽象以及它的实现都应该可以通过生成子类的方法加以扩充。这是Bridge模式使得开发者可以对不同的抽象接口和实现部分进行组合,并分别对它们进行扩充;
对一个抽象的实现部分的修改应对客户不产生影响,即客户代码不必重新编译。
C++想对客户完全隐蔽抽象的实现部分;
有许多类要生成的类层次结构;
想在多个对象间共享实现(可能使用引用计数),但同时要求客户并不知道这一点。
代码案例:
某图像预览程序要求能够查看BMP、JPEG和GIF三种格式的文件,且能够在Windows和Linux两种操作系统上运行。程序需具有较好的扩展性以支持新的文件格式和操作系统。为满足上述需求并减少所需生成的子类数目,现采用桥接模式进行设计。
软件设计师考试2017年下半年下午题第6题
/**
* 桥接模式
*/
public class Bridge {
public static void main(String[] args) {
Implementor implementor1 = new LinuxImp();
Implementor implementor2 = new WinImpl();
//在Linux系统上查看demo.gif图像文件
Image image1 = new GIFImage();
image1.setImpl(implementor1);
image1.parseFile("demo.gif");
//在Windows系统上查看demo.gif图像文件
image1.setImpl(implementor2);
image1.parseFile("demo.gif");
//在Linux系统上查看demo.gif图像文件
Image image2 = new BMPImage();
image2.setImpl(implementor1);
image2.parseFile("demo.bmp");
//在Windows系统上查看demo.gif图像文件
image2.setImpl(implementor2);
image2.parseFile("demo.bmp");
}
}
class Matrix{//各种格式的文件最终都被转化为像素矩阵
private String fileName;//文件名称
public String getFileName() {
return fileName;
}
public void setFileName(String fileName) {
this.fileName = fileName;
}
}
abstract class Implementor{
public abstract void doPaint(Matrix m);//显示像素矩阵m
}
class WinImpl extends Implementor{
@Override
public void doPaint(Matrix m) {
System.out.println("调用windows系统的绘制函数绘制像素矩阵"+m.getFileName());
}
}
class LinuxImp extends Implementor{
@Override
public void doPaint(Matrix m) {
System.out.println("调用Linux系统的绘制函数绘制像素矩阵"+m.getFileName());
}
}
abstract class Image{
protected Implementor impl;
public void setImpl(Implementor impl){
this.impl = impl;
}
public abstract void parseFile(String fileName);
}
class GIFImage extends Image{
@Override
public void parseFile(String fileName) {
//此处解析BMP文件并获得一个像素矩阵对象m
Matrix m = new Matrix();
m.setFileName(fileName);
impl.doPaint(m);//显示像素矩阵m
}
}
class BMPImage extends Image{
@Override
public void parseFile(String fileName) {
//此处解析BMP文件并获得一个像素矩阵对象m
Matrix m = new Matrix();
m.setFileName(fileName);
impl.doPaint(m);//显示像素矩阵m
}
}
class JPEGImage extends Image{
@Override
public void parseFile(String fileName) {
//此处解析BMP文件并获得一个像素矩阵对象m
Matrix m = new Matrix();
m.setFileName(fileName);
impl.doPaint(m);//显示像素矩阵m
}
}
运行结果: