桥接模式
桥接模式属于结构性的一种,它的主要的作用是将抽象部分和现实部分进行分离,将多种可匹配的使用进行了组合。简单的说核心实现就是在A类中含有B类接口,通过构造函数传递B类的实现,这个B类就是设计的桥。
在有多种可能会变化的情况下,用继承会造成类爆炸问题,导致扩展起来不灵活。或者对于两个独立变化的维度,这时使用桥接模式可能是个很好的选择。
JDBC多驱动的实现就是一个很好的例子,再者使用手机进行网上支付时,不同的支付方式搭配上不同的身份验证,也是个很好的例子。
多支付验证模拟桥接模式
目前主流的支付的方式存在支付宝和微信支付,而身份验证主要是人脸识别验证,指纹验证和密码验证。我们可以对支付方式和身份验证进行多匹配,不同的支付方式对应多种身份验证,将支付进行抽象出来,大大的解耦,使其各自变化。
支付方式接口
public interface IPayMode {
//是否支付安全方法 模拟支付验证
boolean security(String uId);
}
人脸支付实现类
public class PayFaceMode implements IPayMode{
protected Logger logger = LoggerFactory.getLogger(PayCypher.class);
public boolean security(String uId) {
logger.info("⼈脸⽀付,⻛控校验脸部识别");
return true;
}
}
指纹支付实现类
public class PayFingerprintMode implements IPayMode{
protected Logger logger = LoggerFactory.getLogger(PayCypher.class);
public boolean security(String uId) {
logger.info("指纹⽀付,⻛控校验指纹信息");
return true;
}
}
密码支付实现类
public class PayCypher implements IPayMode{
protected Logger logger = LoggerFactory.getLogger(PayCypher.class);
public boolean security(String uId) {
logger.info("密码⽀付,⻛控校验环境安全");
return true;
}
}
支付抽象类
public abstract class Pay {
protected Logger logger = LoggerFactory.getLogger(Pay.class);
protected IPayMode payMode;
//构造方法传递实现
public Pay(IPayMode payMode) {
this.payMode = payMode;
}
//pay method
public abstract String transfer(String uId, String tradeId, BigDecimal
amount);
}
微信支付实现类
public class WechatPay extends Pay {
public WechatPay(IPayMode payMode) {
super(payMode);
}
public String transfer(String uId, String tradeId, BigDecimal amount)
{
logger.info("模拟微信渠道⽀付划账开始。uId:{} tradeId:{} amount:{}",
uId, tradeId, amount);
boolean security = payMode.security(uId);
logger.info("模拟微信渠道⽀付⻛控校验。uId:{} tradeId:{} security:
{}", uId, tradeId, security);
if (!security) {
logger.info("模拟微信渠道⽀付划账拦截。uId:{} tradeId:{} amount:
{}", uId, tradeId, amount);
return "0001";
}
logger.info("模拟微信渠道⽀付划账成功。uId:{} tradeId:{} amount:{}",
uId, tradeId, amount);
return "0000";
}
}
支付宝接口实现类
public class AliPay extends Pay {
public AliPay (IPayMode payMode) {
super(payMode);
}
public String transfer(String uId, String tradeId, BigDecimal amount)
{
logger.info("模拟⽀付宝渠道⽀付划账开始。uId:{} tradeId:{} amount:
{}", uId, tradeId, amount);
boolean security = payMode.security(uId);
logger.info("模拟⽀付宝渠道⽀付⻛控校验。uId:{} tradeId:{} security:
{}", uId, tradeId, security);
if (!security) {
logger.info("模拟⽀付宝渠道⽀付划账拦截。uId:{} tradeId:{}
amount:{}", uId, tradeId, amount);
return "0001";
}
logger.info("模拟⽀付宝渠道⽀付划账成功。uId:{} tradeId:{} amount:
{}", uId, tradeId, amount);
return "0000";
}
}
测试
@Test
public void test() {
Pay wechatPay = new WechatPay(new PayFaceMode());
wechatPay.transfer("user0001", "10001", newBigDecimal(100));
}
总结:桥接模式在其实现上符合了设计的单一原则和开闭原则,满足了抽象和实现的分离,增强了扩展能力,但是桥接模式的引入会增加系统的理解与设计难度,由于聚合关联关系建立在抽象层,要求开发者针对抽象进行设计与编程。需要注意的是抽象类构造函数传递实现类和抽象类依赖实现类是实现桥接的关键。