设计模式学习笔记(十)桥接模式
概念
桥接模式是一种软件设计模式,用于将抽象部分和实现部分解耦,并且可以独立地进行扩展。它通过创建一个桥接接口(Bridge Interface),将抽象部分和实现部分分离开来,使它们可以独立地变化。
在桥接模式中,抽象部分包含了高层的抽象逻辑,而实现部分包含了底层的具体实现。通过定义一个桥接接口来连接抽象和实现,客户端可以通过调用抽象部分的接口来使用底层的具体实现。
桥接模式的核心思想是面向接口编程,而不是面向实现编程。它提供了一种灵活的设计方式,可以在运行时动态地改变抽象部分和实现部分之间的关联关系,而不需要修改已有的代码。
●Abstraction(抽象类):用于定义抽象类的接口,它一般是抽象类而不是接口,其中定义了一个Implementor(实现类接口)类型的对象并可以维护该对象,它与Implementor之间具有关联关系,它既可以包含抽象业务方法,也可以包含具体业务方法。
●RefinedAbstraction(扩充抽象类):扩充由Abstraction定义的接口,通常情况下它不再是抽象类而是具体类,它实现了在Abstraction中声明的抽象业务方法,在RefinedAbstraction中可以调用在Implementor中定义的业务方法。
●Implementor(实现类接口):定义实现类的接口,这个接口不一定要与Abstraction的接口完全一致,事实上这两个接口可以完全不同,一般而言,Implementor接口仅提供基本操作,而Abstraction定义的接口可能会做更多更复杂的操作。Implementor接口对这些基本操作进行了声明,而具体实现交给其子类。通过关联关系,在Abstraction中不仅拥有自己的方法,还可以调用到Implementor中定义的方法,使用关联关系来替代继承关系。
●ConcreteImplementor(具体实现类):具体实现Implementor接口,在不同的ConcreteImplementor中提供基本操作的不同实现,在程序运行时,ConcreteImplementor对象将替换其父类对象,提供给抽象类具体的业务操作方法。
示例
示例一
我们拿图形和颜色举例,图形分为圆形、矩形、三角形,颜色分为红色、蓝色、绿色,那么我们则使用桥接模式来实现这个对应关系。
将图形作为固有样式,颜色可以扩充,那么设计如下
1、抽象部分:设一个图形抽象类作为实现类(Implementor),并声明或实现其绘制方法,再创建圆形、矩形、三角形的实现类,来继承此图形接口,作为扩充抽象类(RefinedAbstraction)。
2、实现部分:我们可以将颜色设为一个接口作为实现类接口(Implementor),分别将三种颜色实现这个接口,作为具体实现类(ConcreteImplementor)。
3、桥接模式实现:在抽象部分的实现类,与实现部分的实现类接口是关联关系,因此可以在图形接口中定义颜色接口的变量来实现图形颜色的设置。
代码示例
1、抽象部分
/**
* 图形抽象类
* */
public abstract class ShapeImplementor {
//定义颜色接口类
protected ColorImplementor color = null;
//传入继承颜色接口的具体颜色类,来设置颜色
public void setColor(ColorImplementor color) {
this.color = color;
}
//规范绘制具体操作
public abstract void draw();
}
/**
* 圆形扩充抽象类
* 用来继承图形类的实现类
* */
public class CircleRefinedAbstraction extends ShapeImplementor{
@Override
public void draw() {
System.out.println("绘制" + color.fill() + "颜色的圆形");
}
}
/**
* 矩形扩充抽象类
* 用来继承图形类的实现类
* */
public class RectangleRefinedAbstraction extends ShapeImplementor{
@Override
public void draw() {
System.out.println("绘制" + color.fill() + "颜色的矩形");
}
}
/**
* 三角扩充抽象类
* 用来继承图形类的实现类
* */
public class TriangleRefinedAbstraction extends ShapeImplementor{
@Override
public void draw() {
System.out.println("绘制" + color.fill() + "颜色的三角形");
}
}
2、实现部分
/**
* 颜色实现类接口
* */
public interface ColorImplementor {
//填充颜色方法
public String fill();
}
public class RedConcreteImplementor implements ColorImplementor{
@Override
public String fill() {
return "红色";
}
}
public class GreenConcreteImplementor implements ColorImplementor{
@Override
public String fill() {
return "绿色";
}
}
public class BlueConcreteImplementor implements ColorImplementor{
@Override
public String fill() {
return "蓝色";
}
}
3、客户端
public class Client {
public static void main(String[] args) {
//红色
ColorImplementor color = new RedConcreteImplementor();
//圆形
ShapeImplementor shape = new CircleRefinedAbstraction();
shape.setColor(color);
shape.draw();
}
}
输出结果
绘制红色颜色的圆形
桥接模式与适配器模式联合使用
桥接模式和适配器模式可以结合使用,以实现不同的功能需求。
适配器模式用于将一个类的接口转换成客户端所期望的另一个接口。它通过创建一个适配器(Adapter)类,将原始类的接口与目标接口进行适配,使得原始类可以被客户端使用。
在桥接模式中,抽象部分和实现部分是独立变化的,而适配器模式则是将一个已有的类进行适配以满足客户端的需求。因此,在某些情况下,我们可以将桥接模式和适配器模式联合使用。
例如,假设我们有一个形状绘制程序,其中使用了桥接模式来绘制不同颜色的形状。现在,我们想要引入一个新的类库,该类库提供了一些其他形状,并且使用了不同的接口。
在这种情况下,我们可以使用适配器模式将新的类库中的形状适配到原始类库中的抽象部分和实现部分之间。适配器类充当了一个桥接的角色,将新的类库的接口适配成原始类库的接口,使得它们可以无缝地集成在一起。
总之,桥接模式和适配器模式可以联合使用,以实现不同的功能需求。适配器模式用于将一个类的接口转换成另一个接口,而桥接模式则用于将抽象部分和实现部分解耦。通过结合使用这两种模式,我们可以更灵活地设计和扩展系统。
总结
优点:
1、分离接口和实现,使得两者可以独立变化,从而提高了系统的灵活性和可维护性。
2、桥接模式可以在不破坏原有系统结构的情况下增加新的抽象层次和实现层次,提高系统的可扩展性。
3、可以减少系统中类的个数,简化系统设计和编码。
缺点:
1、增加了系统的复杂性。
2、对于简单的系统,桥接模式可能会带来过度设计的问题。
适用场景:
1、当需要避免或减少抽象和实现之间的紧密耦合时,可以使用桥接模式。
2、当需要扩展抽象和实现之间的继承关系时,可以使用桥接模式。
3、当需要在抽象和实现之间添加新的功能时,可以使用桥接模式。
4、当需要在抽象和实现之间多维度地变化时,可以使用桥接模式。