基本概念
桥接模式(Bridge Pattern)是一种结构设计模式, 将实现和抽象放在两个不同的层次,使得两个层次可以独立改变。基于类最小知道原则,通过聚合继承等行为将不同类承担不同的责任,保证各个类的独立性方便功能扩展。
UML图
角色分析
- Abstraction:抽象类
- RefinedAbstraction:扩充抽象类
- Implementor:实现类接口
- ConcreteImplementor:具体实现类
试想一个手机的需求,手机的品牌有很多IPhone MI Vivo…手机的类型也有多种比如智能机,老年机等如果想要将两种手机的特性组合起来传统的解决方案UML,这样会出现类爆炸,每次拓展都是如笛卡尔积的爆炸增长,而且修改工作巨大,所以提出桥接模式的解决方案将抽象和具体实现抽离层两个不同的层次。
代码演示
//品牌接口 Implementor 实现类接口
public interface Brand {
void open();
void call();
void close();
}
// ConcreteImplementor:具体实现类
public class IPhone implements Brand {
@Override
public void open() {
System.out.println("IPhone 开机");
}
@Override
public void call() {
System.out.println("IPhone 打电话");
}
@Override
public void close() {
System.out.println("IPhone 关机");
}
}
// ConcreteImplementor:具体实现类
public class MIPhone implements Brand {
@Override
public void open() {
System.out.println("MI 开机");
}
@Override
public void call() {
System.out.println("MI 打电话");
}
@Override
public void close() {
System.out.println("MI 关机");
}
}
// Abstraction 抽象类 实现了抽象接口并将抽象接口组合到一起
public abstract class Phone implements Brand{
Brand brand;
public Phone(Brand brand) {
this.brand = brand;
}
public void open() {
brand.open();
}
public void call() {
brand.call();
}
public void close() {
brand.close();
}
}
// RefinedAbstraction 扩充抽象类
public class SmartPhone extends Phone {
public SmartPhone(Brand brand) {
super(brand);
}
@Override
public void open() {
super.open();
System.out.println("Smart Phone");
}
@Override
public void call() {
super.call();
System.out.println("Smart Phone");
}
@Override
public void close() {
super.close();
System.out.println("Smart Phone");
}
}
// RefinedAbstraction 扩充抽象类
public class OldManPhone extends Phone {
public OldManPhone(Brand brand) {
super(brand);
}
@Override
public void open() {
super.open();
System.out.println("OldManPhone");
}
@Override
public void call() {
super.call();
System.out.println("OldManPhone");
}
@Override
public void close() {
super.close();
System.out.println("OldManPhone");
}
}
// 客户端调用
public class BridgeTest {
public static void main(String[] args) {
// 初始化抽象类 Implementor
IPhone iPhone = new IPhone();
MIPhone miPhone = new MIPhone();
System.out.println("===========================================");
// 实例化扩充抽象类
SmartPhone smartPhone = new SmartPhone(iPhone);
smartPhone.open();
smartPhone.call();
smartPhone.close();
System.out.println("===========================================");
SmartPhone smartPhone2 = new SmartPhone(miPhone);
smartPhone2.open();
smartPhone2.call();
smartPhone2.close();
System.out.println("===========================================");
OldManPhone oldManPhone = new OldManPhone(miPhone);
oldManPhone.open();
oldManPhone.call();
oldManPhone.close();
System.out.println("===========================================");
OldManPhone oldManPhone2 = new OldManPhone(iPhone);
oldManPhone2.open();
oldManPhone2.call();
oldManPhone2.close();
System.out.println("===========================================");
}
}
使用细节
-
桥接模式可以替代多继承方案,可以减少子类的数量,减少维护的成本
-
但是桥接模式增加了对系统业务的复杂性和设计难度,在使用桥接模式的时候需要非常清晰的分析出谁是Abstractor 谁是 Implementor这里如果选择不好直接导致桥接模式设计更加复杂,所有桥接模式使用有一定的局限性,一般用于可以出现两种独立变化有大量交叉的情况。
-
常见的场景
如支付系统 以支付方式可以分微信,支付宝,银联等 以用户类型分为普通用户,VIP用户
如验证码 以类型分为图形型 计算型 滑动型 以验证方式分为 手机 邮箱