概念:
桥接模式(Bridge):
结构型设计模式
基于类的最小设计原则,通过使用封装、聚合及继承等行为让不同的类承担不同的职责
把抽象(Abstraction)与行为实现(Implementation)分离开来,从而可以保持各部分的独立性以及应对他们的功能扩展
桥接模式主要包含如下几个角色:
Abstraction:抽象类。
RefinedAbstraction:扩充抽象类。
Implementor:实现类接口。
ConcreteImplementor:具体实现类 。
UML图:
举例:
如遥控器项目,每个厂家的电视对应自己的遥控器。遥控器有打开,关闭,设置频道,设置音量。
传统实现:
遥控器的实现:
package com.cn.bridge.tradition;
/**
* 遥控
*
*/
public interface Control {
void on();
void off();
void setChannel(int ch);
}
package com.cn.bridge.tradition;
public class ATVControl implements Control{
@Override
public void on() {
System.out.println("open ATV ");
}
@Override
public void off() {
System.out.println("close ATV ");
}
@Override
public void setChannel(int ch) {
System.out.println("The ATV set channel " + ch);
}
}
package com.cn.bridge.tradition;
public class BTVControl implements Control{
@Override
public void on() {
System.out.println("open BTV ");
}
@Override
public void off() {
System.out.println("close BTV ");
}
@Override
public void setChannel(int ch) {
System.out.println("The BTV set channel " + ch);
}
}
电视实现:
package com.cn.bridge.tradition;
/**
*TV的功能
*/
public interface TVFunction {
void OnOff();
void nextChannel();
void preChannel();
}
package com.cn.bridge.tradition;
public class ATV extends ATVControl implements TVFunction{
private static int ch=0;
private static boolean ison=false;
@Override
public void OnOff() {
if(ison) {
ison = false;
super.off();
}else {
ison = true;
super.on();
}
}
@Override
public void nextChannel() {
ch++;
super.setChannel(ch);
}
@Override
public void preChannel() {
ch--;
if(ch<0)
{
ch=100;
}
super.setChannel(ch);
}
}
package com.cn.bridge.tradition;
public class BTV extends BTVControl implements TVFunction{
private static int ch=0;
private static boolean ison=false;
@Override
public void OnOff() {
if(ison) {
ison = false;
super.off();
}else {
ison = true;
super.on();
}
}
@Override
public void nextChannel() {
ch++;
super.setChannel(ch);
}
@Override
public void preChannel() {
ch--;
if(ch<0)
{
ch=100;
}
super.setChannel(ch);
}
}
测试:
package com.cn.bridge.tradition;
public class Test {
public static void main(String[] args) {
ATV atv = new ATV();
BTV btv = new BTV();
atv.OnOff();
atv.nextChannel();
atv.preChannel();
atv.OnOff();
btv.OnOff();
btv.nextChannel();
btv.preChannel();
btv.OnOff();
}
}
结果:
open ATV
The ATV set channel 1
The ATV set channel 0
close ATV
open BTV
The BTV set channel 1
The BTV set channel 0
close BTV
电视是现实事物的一个抽象,它里面有遥控的接口的具体实现,如果按照传统的设计,抽象与接口实现的耦合性高,当需要扩充这个抽象类时就会变的很麻烦。
现在我们可以用桥接模式来实现下上面的代码,遥控的接口不变,主要是电视的抽象部分
package com.cn.bridge.now;
import com.cn.bridge.tradition.Control;
/**
* 抽象类角色
*
*/
public abstract class TVFunction {
Control control = null;
public TVFunction(Control control) {
this.control = control;
}
public abstract void OnOff();
public abstract void nextChannel();
public abstract void preChannel();
}
package com.cn.bridge.now;
import com.cn.bridge.tradition.Control;
/**
* 扩充抽象类
* 可以扩充方法等
*
*/
public class TVControl extends TVFunction {
private static int ch=0;
private static boolean ison=false;
public TVControl(Control control) {
super(control);
}
@Override
public void OnOff() {
if(ison) {
ison = false;
control.off();
}else {
ison = true;
control.on();
}
}
@Override
public void nextChannel() {
ch++;
control.setChannel(ch);
}
@Override
public void preChannel() {
ch--;
if(ch<0)
{
ch=100;
}
control.setChannel(ch);
}
public void newMethod() {
System.out.println("自定义的方法");
}
}
package com.cn.bridge.now;
import com.cn.bridge.tradition.ATVControl;
import com.cn.bridge.tradition.BTVControl;
import com.cn.bridge.tradition.Control;
public class Test {
public static void main(String[] args) {
Control acon = new ATVControl();
Control bcon = new BTVControl();
TVControl atv = new TVControl(acon);
atv.OnOff();
atv.nextChannel();
atv.preChannel();
atv.OnOff();
TVControl btv = new TVControl(bcon);
btv.OnOff();
btv.nextChannel();
btv.preChannel();
btv.OnOff();
}
}
结果:
open ATV
The ATV set channel 1
The ATV set channel 0
close ATV
open BTV
The BTV set channel 1
The BTV set channel 0
close BTV
通过分析上述代码,可以发现
桥接模式即将抽象部分与它的实现部分分离开来,使他们都可以独立变化。
桥接模式将继承关系转化成关联关系,它降低了类与类之间的耦合度,减少了系统中类的数量,也减少了代码量。
使用场景:
(1)如果一个系统需要在构件的抽象化角色和具体化角色之间增加更多的灵活性,避免在两个层次之间建立静态的继承联系,通过桥接模式可以使它们在抽象层建立一个关联关系。
(2)抽象化角色和实现化角色可以以继承的方式独立扩展而互不影响,在程序运行时可以动态将一个抽象化子类的对象和一个实现化子类的对象进行组合,即系统需要对抽象化角色和实现化角色进行动态耦合。
(3)一个类存在两个独立变化的维度,且这两个维度都需要进行扩展。
(4)虽然在系统中使用继承是没有问题的,但是由于抽象化角色和具体化角色需要独立变化,设计要求需要独立管理这两者。
(5)对于那些不希望使用继承或因为多层次继承导致系统类的个数急剧增加的系统,桥接模式尤为适用