1.桥接模式定义
桥接模式就是将抽象部分与他的实现部分分离,使他们都可以独立的变化;
桥接模式用一种巧妙地方式处理多层继承存在的问题,用抽象关联来取代传统的多层继承,将类之间的静态继承关系转变为动态的组合关系,使得系统更加灵活,并易于扩展,有效地控制了系统中类的个数;
1.1 桥接模式的优缺点
优点
- 分离抽象接口及其实现部分,桥接模式使用对象间的关联关系解耦了抽象和实现之间固有的绑定关系,使得抽象和实现可以沿着各自的纬度来变化;
- 在很多情况下,桥接模式可以取代多层继承方案,多层继承方案违背了单一职责原则,复用性差,类的个数多;
- 桥接模式提高了系统的可扩展性,在不同变化维度中任意扩展一个纬度不需要修改原有系统,符合开闭原则;
缺点
- 桥接模式的使用会增加系统的理解和设计难度,由于关联关系建立在抽象层,要求开发者一开始就要对抽象层进行设计和编程;
- 桥接模式要求正确识别出系统中的不同变化的维度,需要一定的经验,因此具有一定的局限性;
1.2 桥接模式使用场景
- 需要提供平台独立性的应用程序时,如不同数据库的JDBC驱动程序;
- 需要在某种统一协议下增加更多组件时,如支付场景,行为统一为收款、付款等具体实现为微信、支付宝等;
- 基于消息驱动的场景,行为统一为发送、接收、处理等,具体的实现为短信、邮箱等;
- 拆分复杂的类对象,当一个类包含大量对象和方法;
- 希望从多个独立维度扩展时,如系统功能性和非功能性角度,业务和技术角度;
2.桥接模式的原理
- 抽象化角色(Abstraction):主要负责定义出该角色的行为,并包含一个对现实化对象的引用;
- 扩展抽象化角色(RefinedAbstraction):是抽象化角色的子类,实现父类中的业务方法,并通过组合关系调用实现化角色中的业务方法;
- 实现化角色(Implementor):定义实现化角色的接口,包含角色必须的行为和属性,并供扩展抽象化角色调用;
- 具体实现化角色(Concrete Implementor):给出实现化角色接口的具体实现;
桥接模式我理解的就是由一条主线转为树状结构,将类的不同变化维度分离开;
3.桥接模式实现
【实例】
模拟支付场景,不同的支付工具(支付宝、微信)有着不同的支付方式(密码、指纹)
【代码】
支付模式接口(实现化角色)
public interface IPayMode {//安全校验功能: 对各种支付模式进行风控校验boolean security(String uId);
}
具体支付模式(具体实现化角色)
//指纹支付及风控校验
public class PayFingerprintMode implements IPayMode {@Overridepublic boolean security(String uId) {System.out.println("指纹支付,风控校验-指纹信息");return true;}
}//密码支付及风控校验
public class PayPasswordMode implements IPayMode {@Overridepublic boolean security(String uId) {System.out.println("密码支付,风控校验-环境安全");return false;}
}
支付抽象类(抽象化角色)
public abstract class Pay {//桥接对象protected IPayMode payMode;public Pay(IPayMode payMode) {this.payMode = payMode;}//划账功能public abstract String transfer(String uId, String tradeId, BigDecimal amount);}
支付工具实现(扩展抽象化角色)
public class WxPay extends Pay {public WxPay(IPayMode payMode) {super(payMode);}@Overridepublic String transfer(String uId, String tradeId, BigDecimal amount) {System.out.println("微信渠道支付划账开始......");boolean security = payMode.security(uId);System.out.println("微信渠道支付风险校验: " + uId + " , " + tradeId +" , " + security);if(!security){System.out.println("微信渠道支付划账失败!");return "500";}System.out.println("微信渠道划账成功! 金额: "+ amount);return "200";}
}public class AliPay extends Pay {public AliPay(IPayMode payMode) {super(payMode);}@Overridepublic String transfer(String uId, String tradeId, BigDecimal amount) {System.out.println("支付宝渠道支付划账开始......");boolean security = payMode.security(uId);System.out.println("支付宝渠道支付风险校验: " + uId + " , " + tradeId +" , " + security);if(!security){System.out.println("支付宝渠道支付划账失败!");return "500";}System.out.println("支付宝渠道划账成功! 金额: "+ amount);return "200";}
}
客户端
Pay wxpay = new WxPay(new PayPasswordMode());
wxpay.transfer("wx_00100100","10001900",new BigDecimal(100));Pay aliPay = new AliPay(new PayFingerprintMode());
aliPay.transfer("jlu1234567","567689999999",new BigDecimal(200));