桥接模式(学习笔记2021.09.14)
桥接(Bridge)是用于把抽象化与实现化解耦,使得二者可以独立变化。这种类型的设计模式属于结构型模式,它通过提供抽象化和实现化之间的桥接结构,来实现二者的解耦。
这种模式涉及到一个作为桥接的接口,使得实体类的功能独立于接口实现类。这两种类型的类可被结构化改变而互不影响。
**意图:**将抽象部分与实现部分分离,使它们都可以独立的变化。
**主要解决:**在有多种可能会变化的情况下,用继承会造成类爆炸问题,扩展起来不灵活。
**何时使用:**实现系统可能有多个角度分类,每一种角度都可能变化。
**如何解决:**把这种多角度分类分离出来,让它们独立变化,减少它们之间耦合。
**关键代码:**抽象类依赖实现类。
应用实例: 1、墙上的开关,可以看到的开关是抽象的,不用管里面具体怎么实现的。
优点: 1、抽象和实现的分离。 2、优秀的扩展能力。 3、实现细节对客户透明。
**缺点:**桥接模式的引入会增加系统的理解与设计难度,由于聚合关联关系建立在抽象层,要求开发者针对抽象进行设计与编程。
使用场景: 1、如果一个系统需要在构件的抽象化角色和具体化角色之间增加更多的灵活性,避免在两个层次之间建立静态的继承联系,通过桥接模式可以使它们在抽象层建立一个关联关系。 2、对于那些不希望使用继承或因为多层次继承导致系统类的个数急剧增加的系统,桥接模式尤为适用。 3、一个类存在两个独立变化的维度,且这两个维度都需要进行扩展。
**注意事项:**对于两个独立变化的维度,使用桥接模式再适合不过了。
前提提交:
根据图片说的需求条件, 我们需要改革休息室, 正打算打造一个新的电视机遥控器编程,
使用了好的OO技能将遥控器功能抽象化, 让其他所有不同电视机牌子遥控器基于相同的抽象做不同的实现
问题来了, 我们不会第一次就将抽象化的遥控器与电视机考虑周全, 希望遥控器与电视机能不断的改良,
我们希望能将其设计的能应对不断的改变, 附有弹性, 能根据需求改变实现和抽象。
为何使用桥接模式?
桥梁模式所涉及的角色有:
- 抽象化(Abstraction)角色:抽象化给出的定义,并保存一个对实现化对象的引用。
- 修正抽象化(RefinedAbstraction)角色:扩展抽象化角色,改变和修正父类对抽象化的定义。
- 实现化(Implementor)角色:这个角色给出实现化角色的接口,但不给出具体的实现。必须指出的是,这个接口不一定和抽象化角色的接口定义相同,实际上,这两个接口可以非常不一样。实现化角色应当只给出底层操作,而抽象化角色应当只给出基于底层操作的更高一层的操作。
- 具体实现化(ConcreteImplementor)角色:这个角色给出实现化角色接口的具体实现。
使用桥接模式解决
现在的需求是, 所有的遥控器需要升级, 电视机也需要升级。
以前的实现是, (各个牌子电视机遥控器直接实现了遥控器抽象)
RemoteControl
现在使用桥接模式将电视机抽象化出来=
TV
与RemoteControl
遥控器解耦合, 使其不在相互绑定, 可以独立进行扩展
抽象化(Abstraction)角色
/**
* @Author: ZhiHao
* @Date: 2021/9/14 17:08
* @Description: 抽象的遥控器 - 抽象化(Abstraction)角色
* @Versions 1.0
**/
public abstract class RemoteControl {
// 将电视机抽象化出来, 并持有其引用
protected TV tv;
public RemoteControl(TV tv) {
this.tv = tv;
}
// 打开
abstract void on();
// 关闭
abstract void off();
// 设置频道
abstract void setChannel();
// 电视机加减音量
public void additionAndSubtractionVolume() {
tv.additionAndSubtractionVolume();
}
}
我们可以看到,
RemoteControl
持有了TV
引用,TV
的实例是通过构造函数注入的,这个过程就是我们所说的桥接过程。我们通过这个引用就可以调用TV
的方法,进而将RemoteControl
的行为与TV
的行为通过里面方法
方法而组合起来。
实现化(Implementor)与具体实现角色
/**
* @Author: ZhiHao
* @Date: 2021/9/14 17:32
* @Description: 电视机抽象化
* @Versions 1.0
**/
public interface TV {
// 加减音量
void additionAndSubtractionVolume();
}
----------------------------------------------------------------------------------
/**
* @Author: ZhiHao
* @Date: 2021/9/14 17:43
* @Description: 长虹电视机
* @Versions 1.0
**/
public class ChangHong implements TV {
@Override
public void additionAndSubtractionVolume() {
System.out.println("长虹电视机增加了音量");
}
}
修正抽象化(RefinedAbstraction)角色
/**
* @Author: ZhiHao
* @Date: 2021/9/14 17:56
* @Description: 电视机遥控器, 继承了遥控器抽象,拥有其操作方法
* @Versions 1.0
**/
public class ChangHongRemoteControl extends RemoteControl {
public ChangHongRemoteControl(TV tv) {
super(tv);
}
@Override
public void on() {
System.out.println("打开了长虹电视机");
}
@Override
public void off() {
System.out.println("关闭了长虹电视机");
}
}
测试
@Test
public void applicationTest() throws Exception {
RemoteControl tvRemoteControl = new ChangHongRemoteControl(new ChangHong());
tvRemoteControl.on();
tvRemoteControl.additionAndSubtractionVolume();
}
//-----------------------------------------
打开了长虹电视机
长虹电视机增加了音量
后面遥控器, 先增加了待机功能
public abstract class RemoteControl {
// 将电视机抽象化出来, 并持有其引用
protected TV tv;
// ..................
public abstract void standby();
}
其实现的遥控器
/**
* @Author: ZhiHao
* @Date: 2021/9/14 17:56
* @Description: 长虹遥控器
* @Versions 1.0
**/
public class ChangHongRemoteControl extends RemoteControl {
public ChangHongRemoteControl(TV tv) {
super(tv);
}
// ..................
@Override
public void standby() {
System.out.println("进行了待机");
}
}
但是我们的客户 TV 没有影响到, 可以不做任何修改
测试
public void applicationTest() throws Exception {
TVRemoteControl remoteControl = new ChangHongRemoteControl(new ChangHong());
remoteControl.on();
remoteControl.additionAndSubtractionVolume();
remoteControl.standby();
}
打开了长虹电视机
长虹电视机增加了音量
进行了待机
后面TV电视机增加了健身模式
public interface TV {
// 加减音量
void additionAndSubtractionVolume();
// 添加运动模式
void addFitnessMode();
}
其遥控器抽象
public abstract class RemoteControl {
// 将电视机抽象化出来, 并持有其引用
protected TV tv;
public RemoteControl(TV tv) {
this.tv = tv;
}
// ..................
public void additionAndSubtractionVolume() {
tv.additionAndSubtractionVolume();
}
public void addFitnessMode() {
tv.addFitnessMode();
}
}
但是我们的遥控器实现类没有影响到, 可以不做任何修改
测试
public void applicationTest() throws Exception {
TVRemoteControl remoteControl = new ChangHongRemoteControl(new ChangHong());
// .......
remoteControl.addFitnessMode();
}
打开了长虹电视机
长虹电视机增加了音量
进行了待机
添加开启了健身模式
到此, 电视机与遥控器都升级完成, 都互不影响
1