Java设计模式 桥接模式
目录
桥接模式
在现实生活中,某些类具有多个维度的变化,例如手机分为直板,翻盖,全面屏,它有很多品牌:华为,小米,三星
如果使用集成来做,一共有 m种手机类型
X
n种手机品牌
种组合,会导致类爆炸,且扩展困难的问题。桥接模式将继承转为关联,降低耦合。它将一部分结构分离出去,成为独立的扩展,通过组合的方式来关联。
桥接模式的关键组件
- 桥接接口:独立扩展的结构化接口
- 业务方解耦的抽象类:需要关联桥接接口
- 业务方抽象类的具体实现:
- 桥接接口的具体实现:
业务方和桥接接口之前不会产生强关联
案例代码实现
定义一个接口:Brand
package com.example.spring.boot.test.bridging;
public interface Brand {
/**
* 手机拍照
*/
void camera();
/**
* 手机打电话
*/
void call();
}
创建手机抽象类
package com.example.spring.boot.test.bridging;
public abstract class AbstractPhone {
private final Brand brand;
public AbstractPhone(Brand brand) {
this.brand = brand;
}
public void camera(){
brand.camera();
}
public void call(){
brand.call();
}
}
手机具体的种类
package com.example.spring.boot.test.bridging.impl;
public class FoldedPhone extends AbstractPhone {
public FoldedPhone(Brand brand) {
super(brand);
}
@Override
public void camera() {
// 手机方扩展的功能
System.out.print("折叠手机");
super.camera();
}
@Override
public void call() {
// 手机方扩展的功能
System.out.print("折叠手机");
super.call();
}
}
package com.example.spring.boot.test.bridging.impl;
public class FullScreenPhone extends AbstractPhone {
public FullScreenPhone(Brand brand) {
super(brand);
}
@Override
public void camera() {
// 手机方扩展的功能
System.out.print("全面屏手机");
super.camera();
}
@Override
public void call() {
// 手机方扩展的功能
System.out.print("全面屏手机");
super.call();
}
}
品牌方实现
package com.example.spring.boot.test.bridging.impl;
public class HuaWeiBrand implements Brand {
@Override
public void camera() {
// 品牌方自定义的扩展功能
System.out.println("华为品牌摄像机");
}
@Override
public void call() {
// 品牌方自定义的扩展功能
System.out.println("华为品牌打电话");
}
}
package com.example.spring.boot.test.bridging.impl;
public class XiaoMiBrand implements Brand {
@Override
public void camera() {
// 品牌方自定义的扩展功能
System.out.println("小米品牌摄像机");
}
@Override
public void call() {
// 品牌方自定义的扩展功能
System.out.println("小米品牌打电话");
}
}
测试
package com.example.spring.boot.test.bridging;
public class BridgingTest {
public static void main(String[] args) {
// 创建两个类型的手机
FullScreenPhone fullScreenHuaWeiPhone = new FullScreenPhone(new HuaWeiBrand());
FullScreenPhone fullScreenXiaoMiPhone = new FullScreenPhone(new XiaoMiBrand());
FoldedPhone foldedHuaWeiPhone = new FoldedPhone(new HuaWeiBrand());
FoldedPhone foldedXiaoMiPhone = new FoldedPhone(new XiaoMiBrand());
fullScreenHuaWeiPhone.camera();
fullScreenXiaoMiPhone.camera();
foldedHuaWeiPhone.camera();
foldedXiaoMiPhone.camera();
}
}
结果
全面屏手机华为品牌摄像机
全面屏手机小米品牌摄像机
折叠手机华为品牌摄像机
折叠手机小米品牌摄像机
如果我们在后续业务中,增加了三星品牌,只需要新创建一个实现类实现Brand
接口即可
桥接模式的优点
- 抽象和实现分离
- 优秀的扩展能力
- 在生活中,会遇见很多多维度的事物,使用继承来解决的话,类很多,且代码复用性较差,桥接模式最为合适
- 桥接模式增强了系统的扩展性,两个纬度中任意扩展,不会修改原有代码逻辑,符合开闭原则
使用场景
- 对于某些不希望使用集成或多层次继承导致类个数增加的系统,采用桥接模式
- 一个类存在两个独立变化的维度,且这两个维度都有扩展的可能
桥接模式和适配器模式的区别
两种模式使用场景不同,适配器主要解决两个已经实现的系统或接口,之间匹配的问题,被适配的(外部)接口是一个黑匣子,我们不想,也不能去修改这个接口的实现。我们只需要他配合我们的系统工作即可。通常在对接第三方系统或接口时采用适配器模式。
桥接模式中参与桥接的接口是稳定的,用户可以扩展和修改桥接接口的实现类,但是不能修改接口。桥接模式通过接口继承或类继承实现功能扩展。
==所以桥接模式用于设计的前期,在设计类时,将类规划为逻辑和实现两大类,他们可以分别演化;适配器在程序设计完成后,发现设计完成的类无法协同工作,这个时候采用适配器模式。==