桥接模式是一种很实用的结构型设计模式,如果软件系统中某个类存在两个独立变化的维度,通过该模式可以将这两个维度分离出来,使两者可以独立扩展,让系统变得更加符合SRP。
比如,设计一个跨平台的图像浏览系统,支持的图片格式包括:
等等,而支持的系统包括:
等等,这样,系统与图片格式就是两个不同的维度,可以利用桥接模式将这两个维度分离,使得它们可以独立变化,增加新的图片格式或者新的系统时,都不会对另一个维度造成任何影响。
桥接模式:将抽象部分与其实现部分分离,使它们都可以独立地变化。
它是一种对象结构型模式,又称为柄体模式或者接口模式。
Abstraction
(抽象类):用于定义抽象类的接口,一般是抽象类而不是接口,具有一个Implementor
的成员,与Implementor
为关联关系,既可以包含抽象的业务方法,也可以包含具体业务方法RefinedAbstraction
(扩充抽象类):扩充由Abstraction
定义的接口,通常为具体类,实现了在Abstraction
中的抽象业务方法,同时可以调用Implementor
中的业务方法Implementor
(实现类接口):实现类的接口,相比起Abstractoin
提供的更多更复杂的操作,Implementor
一般只提供基本操作,具体实现交由子类处理ConcreteImplementor
(具体实现类):具体实现Implementor
接口,不同的ConcreteImplementor
提供不同实现的基本操作首先对系统中独立变化的维度进行识别,比如有两个维度(A与B),其中A设计为抽象类,B设计为接口:
abstract class DimensionA{}
interface DimensionB{}
接着是建立抽象耦合,A维度包含一个B维度成员,将B维度作为setter参数传入A维度,同时定义两个普通方法:
abstract class DimensionA
{
protected DimensionB dimensionB;
public abstract void methodA();
public void setDimensionB(DimensionB dimensionB)
{
this.dimensionB = dimensionB;
}
}
interface DimensionB
{
void methodB(String str);
}
接着是扩充抽象类以及具体类实现,维度A有三个具体类,维度B有两个具体类:
class A1 extends DimensionA
{
@Override
public void methodA()
{
dimensionB.methodB("A1");
}
}
class A2 extends DimensionA
{
@Override
public void methodA()
{
dimensionB.methodB("A2");
}
}
class A3 extends DimensionA
{
@Override
public void methodA()
{
dimensionB.methodB("A3");
}
}
class B1 implements DimensionB
{
@Override
public void methodB(String str)
{
System.out.println("B1---"+str);
}
}
class B2 implements DimensionB
{
@Override
public void methodB(String str)
{
System.out.println("B2---"+str);
}
}
针对抽象层(两个维度)进行编程,将B维度作为setter参数传入A维度,接着调用A维度的方法:
public static void main(String[] args)
{
DimensionA dimensionA = new A1();
dimensionA.setDimensionB(new B1());
dimensionA.methodA();
}
跨平台的图片浏览系统,支持的图片格式包括PNG,JPG,BMP,GIF等,支持的系统包括Linux,Unix,Windows等,使用桥接模式设计。
设计如下:
Image
,Image
具有一个ImageShow
的成员变量BMP
,GIF
等继承Image
ImageShow
Linux
,Unix
,Windows
实现图片显示接口ImageShow
代码如下:
public class Test
{
public static void main(String[] args) {
Image image = new GIF();
image.setImageShow(new Linux());
image.show();
}
}
//Image抽象类
abstract class Image
{
protected ImageShow imageShow;
public void setImageShow(ImageShow imageShow)
{
this.imageShow = imageShow;
}
public abstract show();
}
class BMP extends Image
{
@Override
public void show()
{
imageShow.show("BMP");
}
}
class GIF extends Image
{
@Override
public void show()
{
imageShow.show("GIF");
}
}
class PNG extends Image
{
@Override
public void show()
{
imageShow.show("PNG");
}
}
class JPG extends Image
{
@Override
public void show()
{
imageShow.show("JPG");
}
}
//图片显示接口
interface ImageShow
{
void show(String name);
}
class Windows implements ImageShow
{
@Override
public void show(String name)
{
System.out.println("Windows show "+name);
}
}
class Linux implements ImageShow
{
@Override
public void show(String name)
{
System.out.println("Linux show "+name);
}
}
class Unix implements ImageShow
{
@Override
public void show(String name)
{
System.out.println("Unix show "+name);
}
}
更换图片格式只需要修改Image
的父类:
Image image = new GIF();
Image image = new BMP();
Image image = new JPG();
Image image = new PNG();
而更换操作系统只需要修改传入setter的参数:
image.setImageShow(new Linux());
image.setImageShow(new Windows());
image.setImageShow(new Unix());
这样就可以把图片以及系统两个维度分离,并能够独立扩展,增加新的图片格式,只需要增加一个新的继承Image
的类即可,增加新的系统只需实现ImageShow
接口即可。
由于例子简单使用反射进行简化代码并增加了新的系统以及图片格式,代码如下:
public class Test
{
public static void main(String[] args) {
Image image = new WBEP();
image.setImageShow(new Mac());
image.show();
}
}
abstract class Image
{
protected ImageShow imageShow;
public void setImageShow(ImageShow imageShow)
{
this.imageShow = imageShow;
}
public void show()
{
imageShow.show(getClass().getName());
}
}
class BMP extends Image{}
class GIF extends Image{}
class PNG extends Image{}
class JPG extends Image{}
class WBEP extends Image{}
interface ImageShow
{
void show(String name);
}
abstract class ImageSystem implements ImageShow
{
public void show(String name)
{
System.out.println(getClass().getName()+" show "+name);
}
}
class Windows extends ImageSystem{}
class Linux extends ImageSystem{}
class Unix extends ImageSystem{}
class Mac extends ImageSystem{}
如果觉得文章好看,欢迎点赞。
同时欢迎关注微信公众号:氷泠之路。