定义
桥接(Bridge)是用于把抽象化与实现化解耦,使得二者可以独立变化。这种类型的设计模式属于结构型模式,它通过提供抽象化和实现化之间的桥接结构,来实现二者的解耦。
这种模式涉及到一个作为桥接的接口,使得实体类的功能独立于接口实现类。这两种类型的类可被结构化改变而互不影响。
介绍
意图:将抽象部分与实现部分分离,使它们都可以独立的变化。
主要解决:在有多种可能会变化的情况下,用继承会造成类爆炸问题,扩展起来不灵活。
何时使用:实现系统可能有多个角度分类,每一种角度都可能变化。
如何解决:把这种多角度分类分离出来,让它们独立变化,减少它们之间耦合。
关键代码:抽象类依赖实现类
优点: 1、抽象和实现的分离。 2、优秀的扩展能力。 3、实现细节对客户透明。
缺点:桥接模式的引入会增加系统的理解与设计难度,由于聚合关联关系建立在抽象层,要求开发者针对抽象进行设计与编程。
使用场景: 1、如果一个系统需要在构件的抽象化角色和具体化角色之间增加更多的灵活性,避免在两个层次之间建立静态的继承联系,通过桥接模式可以使它们在抽象层建立一个关联关系。 2、对于那些不希望使用继承或因为多层次继承导致系统类的个数急剧增加的系统,桥接模式尤为适用。 3、一个类存在两个独立变化的维度,且这两个维度都需要进行扩展。
注意事项:对于两个独立变化的维度,使用桥接模式再适合不过了。
图示
在桥接模式结构图中包含如下几个角色:
Abstraction(抽象类):用于定义抽象类的接口,它一般是抽象类而不是接口,其中定义了一个 Implementor(实现类接口)类型的对象并可以维护该对象,它与 Implementor 之间具有关联关系,它既可以包含抽象业务方法,也可以包含具体业务方法。例子中的AbsTeacher类。
RefinedAbstraction(扩充抽象类):扩充由 Abstraction 定义的接口,通常情况下它不再是抽象类而是具体类,它实现了在 Abstraction 中声明的抽象业务方法,在 RefinedAbstraction 中可以调用在 Implementor 中定义的业务方法。例子中的XiaoHong,XiaoMing类
Implementor(实现类接口):定义实现类的接口,这个接口不一定要与 Abstraction 的接口完全一致,事实上这两个接口可以完全不同,一般而言,Implementor 接口仅提供基本操作,而 Abstraction 定义的接口可能会做更多更复杂的操作。Implementor 接口对这些基本操作进行了声明,而具体实现交给其子类。通过关联关系,在 Abstraction 中不仅拥有自己的方法,还可以调用到 Implementor 中定义的方法,使用关联关系来替代继承关系。例子中的ICourse类
ConcreteImplementor(具体实现类):具体实现 Implementor 接口,在不同的 ConcreteImplementor 中提供基本操作的不同实现,在程序运行时,ConcreteImplementor 对象将替换其父类对象,提供给抽象类具体的业务操作方法。例子中的Math,Chinese类
举例
package com.example.javatest;
public class BrigeDesignPattern {
static abstract class AbstractTeacher {//Abstraction
private ICourse mCourse;//组合关系
private String mName;
public AbstractTeacher(String name, ICourse course) {
mCourse = course;
mName = name;
}
public ICourse getCourse() {
return mCourse;
}
public abstract void doing();
public String getName(){
return mName;
}
public void setCourse(ICourse course) {
mCourse = course;
}
}
interface ICourse{//Implementor
String courseName();
}
static class XiaoMing extends AbstractTeacher {//RefinedAbstraction
public XiaoMing(ICourse course) {
super("小明", course);
}
@Override
public void doing() {
System.out.println(getName() + "老师正在教" + getCourse().courseName());
}
}
static class XiaoHong extends AbstractTeacher{//RefinedAbstraction
public XiaoHong(ICourse course) {
super("小红", course);
}
@Override
public void doing() {
System.out.println(getName() + "老师正在批改" + getCourse().courseName() + "试卷");
}
}
static class Math implements ICourse{//ConcreteImplementor
@Override
public String courseName() {
return "数学课";
}
}
static class Chinese implements ICourse{//ConcreteImplementor
@Override
public String courseName() {
return "语文课";
}
}
public static void main(String[] args){
ICourse math = new Math();
ICourse chinese = new Chinese();
AbstractTeacher xiaoming = new XiaoMing(math);
AbstractTeacher xiaohong = new XiaoHong(chinese);
xiaoming.doing();
xiaohong.doing();
xiaohong.setCourse(math);
xiaoming.setCourse(chinese);
xiaohong.doing();
xiaoming.doing();
}
}
输出
小明老师正在教数学课
小红老师正在批改语文课试卷
小红老师正在批改数学课试卷
小明老师正在教语文课