7.桥接模式
一、什么是桥接模式
将实现与抽象放在两个不同的类层次中,使两个层次可以独立改变。它是一种结构型设计模式。
Bridge 模式基于类的最小设计原则,通过使用封装、聚合及继承等行为让不同的类承担不同的职责。它的主要特点是把抽象(Abstraction)与行为实现(Implementation)分离开来,从而可以保持各部分的独立性以及应对他们的功能扩展。
二、原理图
原理类图说明:
- Client 类:桥接模式的调用者
- 抽象类(Abstraction):维护了 Implementor,即它的实现类 ConcreteImplementorA/B,二者是聚合关系, Abstraction充当桥接
- RefinedAbstraction:是 Abstraction 抽象类的子类
- Implementor:行为实现类的接口
- ConcreteImplementorA /B:行为的具体实现类
- 这里的抽象类和接口是聚合的关系,其实也是调用和被调用关系
三、具体需求
1.手机操作问题
现在对不同手机类型的不同品牌实现操作编程,比如:开机、关机、上网,打电话等。如图:
2. 传统方案
思路分析 - 类图
传统方式分析
- 扩展性问题(会产生类爆炸),如果我们再增加手机的样式(旋转式),就需要增加各个品牌手机的类,同样如果我们增加一个手机品牌,也要在各个手机样式类下增加
- 违反了单一职责原则,当我们增加手机样式时,要同时增加所有品牌的手机,这样增加了代码维护成本
- 解决方案-使用桥接模式
3. 桥接模式方案
使用桥接模式改进传统方式,让程序具有更好的扩展性
思路分析 - 类图
编码:
package com.qfedu.mode.bridge;
/**
* 品牌接口
*
* @ClassName Brand
* @Author ykx
* @Date 2022/10/22 19:06
* @Version 1.0
*/
public interface Brand {
void open();
void call();
void close();
}
品牌接口实现类vivo:
package com.qfedu.mode.bridge;
/**
* @ClassName Vivo
* @Author ykx
* @Date 2022/10/22 19:07
* @Version 1.0
*/
public class Vivo implements Brand {
@Override
public void open() {
System.out.println("vivo手机开机");
}
@Override
public void call() {
System.out.println("vivo手机打电话");
}
@Override
public void close() {
System.out.println("vivo手机关机");
}
}
xiaomi:
package com.qfedu.mode.bridge;
/**
* @ClassName Xiaomi
* @Author ykx
* @Date 2022/10/22 19:08
* @Version 1.0
*/
public class Xiaomi implements Brand {
@Override
public void open() {
System.out.println("xiaomi手机开机");
}
@Override
public void call() {
System.out.println("xiaomi手机打电话");
}
@Override
public void close() {
System.out.println("xiaomi手机关机");
}
}
抽象类Phone:
package com.qfedu.mode.bridge;
/**
* @ClassName Phone
* @Author ykx
* @Date 2022/10/22 19:09
* @Version 1.0
*/
public abstract class Phone {
private Brand brand;//聚合
public Phone(Brand brand) {
this.brand = brand;
}
public void open() {
this.brand.open();
}
public void close() {
this.brand.close();
}
public void call() {
this.brand.call();
}
}
不同样式的手机(Folder折叠式):
package com.qfedu.mode.bridge;
/**
* @ClassName FoldedPhone
* @Author ykx
* @Date 2022/10/22 19:11
* @Version 1.0
*/
public class FoldedPhone extends Phone {
public FoldedPhone(Brand brand) {
super(brand);
}
public void open() {
super.open();
System.out.println("折叠样式手机");
}
public void close() {
super.close();
System.out.println("折叠样式手机");
}
public void call() {
super.call();
System.out.println("折叠样式手机");
}
}
直立样式(Upright)
package com.qfedu.mode.bridge;
/**
* @ClassName UprightPhone
* @Author ykx
* @Date 2022/10/22 19:12
* @Version 1.0
*/
public class UprightPhone extends Phone {
public UprightPhone(Brand brand) {
super(brand);
}
public void open() {
super.open();
System.out.println("直立手机");
}
public void close() {
super.close();
System.out.println("直立手机");
}
public void call() {
super.call();
System.out.println("直立手机");
}
}
客户端测试类:(红色部分分别可构造不同的手机样式与品牌)
public class BridgeTest {
public static void main(String[] args) {
Phone phone = new FoldedPhone(new Xiaomi());
phone.call();
}
}