Hexo

点滴积累 豁达处之

0%

08 桥接模式

桥接模式(Bridge)是一种结构型设计模式。Bridge模式基于类的最小设计原则,通过使用封装、聚合及继承等行为让不同的类承担不同的职责。它的主要特点是把抽象(Abstraction)与行为实现(Implementation)分离开来,从而可以保持各部分的独立性以及应对他们的功能扩展。

桥接模式

​ 桥接是一个接口,它与一方应该是绑定的,也就是解耦的双方中的一方必然是继承这个接口的,这一方就是实现方,而另一方正是要与这一方解耦的抽象方,如果不采用桥接模式,一般我们的处理方式是直接使用继承来实现,这样双方之间处于强链接,类之间关联性极强,如要进行扩展,必然导致类结构急剧膨胀。采用桥接模式,正是为了避免这一情况的发生,将一方与桥绑定,即实现桥接口,另一方在抽象类中调用桥接口(指向的实现类),这样桥方可以通过实现桥接口进行单方面扩展,而另一方可以继承抽象类而单方面扩展,而之间的调用就从桥接口来作为突破口,不会受到双方扩展的任何影响。

1 示例

​ 实例准备:我们假设有一座桥,桥左边为A,桥右边为B,A有A1,A2,A3等,表示桥左边的三个不同地方,B有B1,B2,B3等,表示桥右边的三个不同地方,假设我们要从桥左侧A出发到桥的右侧B,我们可以有多重方案,A1到B1,A1到B2,A1到B3,A2到B1…等等,以此为例,代码如下:

桥接口:Qiao

1
2
3
4
public interface Qiao {
//目的地B
void targetAreaB();
}

目的地B1,B2,B3:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
 /**
* 目的地B1
*/
public class AreaB1 implements Qiao {
@Override
public void targetAreaB() {
System.out.println("我要去B1");
}
}

/**
* 目的地B2
*/
public class AreaB2 implements Qiao {
@Override
public void targetAreaB() {
System.out.println("我要去B2");
}
}

/**
* 目的地B3
*/
public class AreaB3 implements Qiao {
@Override
public void targetAreaB() {
System.out.println("我要去B3");
}
}

抽象来源地A:AreaA

1
2
3
4
5
6
public abstract class AreaA {
//引用桥接口
Qiao qiao;
//来源地
abstract void fromAreaA();
}

来源地A1,A2,A3:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
/**
* 来源地A1
*/
public class AreaA1 extends AreaA {
@Override
void fromAreaA() {
System.out.println("我来自A1");
}
}

/**
* 来源地A2
*/
public class AreaA2 extends AreaA {
@Override
void fromAreaA() {
System.out.println("我来自A2");
}
}

/**
* 来源地A3
*/
public class AreaA3 extends AreaA {
@Override
void fromAreaA() {
System.out.println("我来自A3");
}
}

测试类:Clienter

1
2
3
4
5
6
7
8
public class Clienter {
public static void main(String[] args) {
AreaA a = new AreaA2();
a.qiao = new AreaB3();
a.fromAreaA();
a.qiao.targetAreaB();
}
}

运行结果:

1
2
我来自A2
我要去B3

​ 现在我们要添加来源地和目的地,只要继续继承AreaA和实现Qiao即可,之前我所说的绑定,正式此处将桥与目的地绑定在一起,使用一个接口完成。

​ 其实要完成桥接模式,注意点并不多,重在理解模式的使用场景。

  注意点:

    1、定义一个桥接口,使其与一方绑定,这一方的扩展全部使用实现桥接口的方式。

    2、定义一个抽象类,来表示另一方,在这个抽象类内部要引入桥接口,而这一方的扩展全部使用继承该抽象类的方式。

  其实我们可以发现桥接模式应对的场景有方向性的,桥绑定的一方都是被调用者,属于被动方,抽象方属于主动方。

2 桥接模式的优点

(1)实现了抽象和实现部分的分离

​ 桥接模式分离了抽象部分和实现部分,从而极大的提供了系统的灵活性,让抽象部分和实现部分独立开来,分别定义接口,这有助于系统进行分层设计,从而产生更好的结构化系统。对于系统的高层部分,只需要知道抽象部分和实现部分的接口就可以了。

(2)更好的可扩展性

​ 由于桥接模式把抽象部分和实现部分分离了,从而分别定义接口,这就使得抽象部分和实现部分可以分别独立扩展,而不会相互影响,大大的提供了系统的可扩展性。

(3)可动态的切换实现

​ 由于桥接模式实现了抽象和实现的分离,所以在实现桥接模式时,就可以实现动态的选择和使用具体的实现。

(4)实现细节对客户端透明,可以对用户隐藏实现细节。

3 桥接模式的缺点

(1)桥接模式的引入增加了系统的理解和设计难度,由于聚合关联关系建立在抽象层,要求开发者针对抽象进行设计和编程。

(2)桥接模式要求正确识别出系统中两个独立变化的维度,因此其使用范围有一定的局限性。

4 桥接模式的使用场景

(1)如果一个系统需要在构件的抽象化角色和具体化角色之间增加更多的灵活性,避免在两个层次之间建立静态的继承联系,通过桥接模式可以使它们在抽象层建立一个关联关系。

(2)抽象化角色和实现化角色可以以继承的方式独立扩展而互不影响,在程序运行时可以动态将一个抽象化子类的对象和一个实现化子类的对象进行组合,即系统需要对抽象化角色和实现化角色进行动态耦合。

(3)一个类存在两个独立变化的维度,且这两个维度都需要进行扩展。

(4)虽然在系统中使用继承是没有问题的,但是由于抽象化角色和具体化角色需要独立变化,设计要求需要独立管理这两者。

(5)对于那些不希望使用继承或因为多层次继承导致系统类的个数急剧增加的系统,桥接模式尤为适用

参考链接