将抽象部分与实现部分分离开来,使得两者能够独立变化,互不影响的结构型设计模式。设计模式
抽象部分(Abstraction) : 该类保持一个对实现部分的引用,抽象部分中的方法须要调用实现部分的对象的方法来实现;这部分通常为抽象类居多。bash
具体抽象部分(Concrete Abstraction):
抽象部分的具体实现,通常用于抽象部分方法的完善和扩展;框架
实现部分(Implementor) : 能够为接口或抽象类,其方法不必定要与抽象部分中的一致,通常状况下是由实现部分提供基本的操做,而抽象部分定义的则是基于实现部分这些基本操做的业务方法;ide
具体实现部分(Concrete Implementor): 实现完善"实现部分"定义的相关接口功能;this
客户端(Client): 客户类,客户端程序 (调用程序的地方)spa
实现部分(Implementor) : Line"线",抽象为接口类,方法为Draw"画线"。设计
具体实现部分(Concrete Implementor): 实现Line功能的子类,例如SolidLine绘制实线、DottedLine绘制虚线。code
抽象部分(Abstraction): 形状Shape,持有一个Implementor的引用,并定义出须要借助Implementor来实现的方法,好比使用“线"绘制出形状cdn
具体抽象部分(Concrete Abstraction): Abstraction的实现类,完善扩展Implementor的方法。好比三角形、矩形、圆形等,绘制出各自的图形对象
能够看到Implementor和Abstraction有相对明显的上下级,Abstraction须要调用Implementor来实现目的,是Implementor上级。
实现部分(Implementor):
public interface Line {
void draw();
}
复制代码
具体实现部分(Concrete Implementor):
public class SolidLine implements Line {
@Override
public void draw() {
//...
System.out.println("绘制实线");
}
}
复制代码
public class GottedLine implements Line {
@Override
public void draw() {
//...
System.out.println("绘制虚线");
}
}
复制代码
抽象部分(Abstraction):
public abstract class Shape {
//持有一个实现部分Implementor引用
Line line;
public Shape(Line line) {
this.line = line;
}
public abstract void drawShape();
}
复制代码
具体抽象部分(Concrete Abstraction):
public class Circular extends Shape {
public Circular(Line line) {
super(line);
}
@Override
public void drawShape() {
//...
line.draw();
System.out.println("绘制出圆形");
//...
}
}
复制代码
public class Rectangle extends Shape {
public Rectangle(Line line) {
super(line);
}
@Override
public void drawShape() {
//...
line.draw();
System.out.println("绘制出矩形");
//...
}
}
复制代码
客户端调用示例:
//使用实线绘制圆形
Circular solidCircular = new Circular(new SolidLine());
solidCircular.drawShape();
//使用虚线绘制圆形
Circular gottedCircular = new Circular(new GottedLine());
gottedCircular.drawShape();
//使用实线绘制矩形
Rectangle solidRectangle = new Rectangle(new SolidLine());
solidRectangle.drawShape();
//使用虚线绘制矩形
Rectangle gottedRectangle = new Rectangle(new GottedLine());
gottedRectangle.drawShape();
复制代码
上述例子假设没使用桥接模式,很明显会出现"类爆炸"的问题,类数量出现快速增长:
那么当实现的类个数为m * n ,之后不管多增长一种形状(增长m个线数量的实现类),或者多增长一种线(增长n个形状的实现类),(在基数足够大的状况下)都会爆炸式的增长太多的实现类。
而若是如上使用桥接模式,不管是增长形状(抽象部分)、线(实现部分),理论上都只须要增长各自的一个具体实现,实现了抽象部分和实现部分能够独立修改互不影响。
桥接模式通常用于存在上下级关系的二维变化系统中,将底层的部分分割为实现层,将较上层的部分分割为抽象层。 抽象层中的方法实现实际依赖于实现层对象的方法。
分离抽象和实现部分: 桥接模式分离了抽象和实现部分,从而极大地提升了系统的灵活性。让抽象部分和实现部分独立开来,分别定义接口,这有助于对系统进行分层,从而产生更好的结构化的系统。对于系统的高层部分,只须要知道抽象部分和实现部分的接口就能够了。
灵活的扩展性: 因为桥接模式把抽象和实现部分分离开了,并且分别定义接口,这就使得抽象部分和实现部分能够分别独立的扩展,而不会相互影响,从而大大的提升了系统的可扩展性。可动态切换实现。 因为桥接模式把抽象和实现部分分离开了,那么在实现桥接的时候,就能够实现动态的选择和使用具体的实现,也就是说一个实现再也不是固定的绑定在一个抽象接口上了,能够实现运行期间动态的切换实现。
实际应用中相对不容易设计,由于判断哪部分做为实现部分,哪部分做为抽象部分对开发者要有必定的经验要求。
若是一个系统须要在构件的抽象化角色和具体化角色之间增长更多的灵活性,避免在两个层次之间创建静态的继承关系,能够经过桥接模式使他们在抽象层创建一个关联关系。 对于那些不但愿使用继承或由于多层次继承致使系统类的个数急剧增长的系统,也能够考虑使用桥接模式。 一个类存在两个独立变化的维度,且这两个维度都须要进行扩展。
1.桥接模式能够作到的感受装饰者模式好像也能够作到,两者的区别?
装饰者模式支持使用多个装饰者屡次装饰被装饰者,而且要求装饰者和被装饰者提供一致的接口行为,接口要求返回的也是统一的被装饰者接口对象。 而桥接模式通常用一个抽象部分来扩展完善实现部分,并不要求提供一致的接口行为。
装饰者模式通常没有明显的上下级依赖关系,可是桥接模式的2个维度每每会有上下级依赖关系的存在。
2.怎么判断哪部分做为实现部分,哪部分做为抽象部分?
通常是真正的"实现"部分(被依赖的部分)做为实现部分,上层做为抽象部分,能够从例子中理会,由于要绘制形状须要依赖于绘制线,绘制线实际上是真正的实现部分,绘制形状只是把绘制的线进行拼接(扩展完善了线的功能做用,封装业务功能等)。因此线是实现部分,形状是抽象部分。