1.基本介绍
桥接模式(Bridge模式) 是指:将实现与抽象放在两个不同的类层次中,使两个层 次可以独立改变。 该模式是一种结构型设计模式。
我们看一下网络上对该模式的解释:
Bridge模式 基于类的最小设计原则,通过使用封装、聚合及继承等行为让不同的类承担不同的职责。它的主要特点是把抽象(Abstraction)与行为实现 (Implementation)分离开来,从而可以保持各部分的独立性以及应对他们的功能扩展。
看完描述后可能仍感觉是云里雾里,我们通过一个实际的案例来分析桥接模式。
需求:如下图所示,设想一个手机品牌问题。
手机的品牌和手机的外在构造方式各有许多种,如果它们每个都是一个类的话,我们一般是这样来实现的:
如上图所示,但是这样的设计会造成一些问题:
第一个是类爆炸问题,当我们新加入一种手机设计形态或者新加入一个手机品牌时,就需要增加很多类的编写,增加了代码维护成本。这时可以采取桥接模式。
2.代码实现
上述手机案例使用桥接模式时的类图如下:
我们直接通过代码来直观展现桥接模式的优点。
接口Brand,让具体的手机品牌类实现该接口
package bridge;
/**
* @Author Worm
* @Date 2020/8/12 22:53
* @Version 1.0
**/
public interface Brand {
void open();
void close();
void call();
}
两个具体手机品牌类
package bridge;
/**
* @Author Worm
* @Date 2020/8/12 22:55
* @Version 1.0
**/
public class ViVo implements Brand {
@Override
public void open() {
System.out.println("vivo开机");
}
@Override
public void close() {
System.out.println("vivo关机");
}
@Override
public void call() {
System.out.println("vivo打电话");
}
}
package bridge;
/**
* @Author Worm
* @Date 2020/8/12 22:54
* @Version 1.0
**/
public class XiaoMi implements Brand {
@Override
public void open() {
System.out.println("小米开机了");
}
@Override
public void close() {
System.out.println("小米关机了");
}
@Override
public void call() {
System.out.println("小米打电话");
}
}
phone抽象类,持有一个Brand对象。
package bridge;
/**
* @Author Worm
* @Date 2020/8/12 22:56
* @Version 1.0
**/
public abstract class Phone {
private Brand brand;
public Phone(Brand brand) {
this.brand = brand;
}
protected void open() {
brand.open();
}
protected void close() {
brand.close();
}
protected void call() {
brand.call();
}
}
两个具体的手机设计方式类继承phone抽象类
package bridge;
import java.util.Queue;
/**
* @Author Worm
* @Date 2020/8/12 23:02
* @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("折叠式手机");
}
}
package bridge;
/**
* @Author Worm
* @Date 2020/8/12 23: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("直立样式手机");
}
}
客户端:
package bridge;
/**
* @Author Worm
* @Date 2020/8/12 23:10
* @Version 1.0
**/
public class client {
public static void main(String[] args) {
FoldedPhone foldedPhone = new FoldedPhone(new XiaoMi());
foldedPhone.open();
foldedPhone.call();
foldedPhone.close();
System.out.println("==================");
FoldedPhone foldedPhone1=new FoldedPhone(new ViVo());
foldedPhone1.open();
foldedPhone1.close();
foldedPhone1.call();
System.out.println("==================");
UprightPhone uprightPhone = new UprightPhone(new XiaoMi());
uprightPhone.call();
uprightPhone.close();
uprightPhone.call();
}
}
3.桥接模式总结
可以看到,现在当我们想增加一个手机品牌或增加一种新的手机设计方式时,只需要添加一个相关的具体实现类,使系统结构更加优化,提高了灵活性。桥接模式替代多层继承方案,可以减少子类的个数。
桥接模式要求针对特定应用场景正确识别出系统中两个独立变化的维度(抽象和实现)。
常见的应用场景:
1.JDBC驱动程序
2.银行转账系统:转账分类有网上转账,柜台转账,ATM转账等。转账的用户类型有普通用户,银卡用户等……
3.消息管理:消息类型有即时消息和延时消息等,消息分类有手机短信,邮件消息等……