Luckylau's Blog

设计模式之桥接模式

​ 桥接(Bridge)是用于把抽象化与实现化解耦,使得二者可以独立变化。这种类型的设计模式属于结构型模式,它通过提供抽象化和实现化之间的桥接结构,来实现二者的解耦。这种模式涉及到一个作为桥接的接口,使得实体类的功能独立于接口实现类。这两种类型的类可被结构化改变而互不影响。

桥接模式的使用场景:

1.如果一个系统需要在构件的抽象化角色和具体化角色之间增加更多的灵活性,避免在两个层次之间建立静态的继承联系,通过桥接模式可以使它们在抽象层建立一个关联关系。

2.对于那些不希望使用继承或因为多层次继承导致系统类的个数急剧增加的系统,桥接模式尤为适用。

3.一个类存在两个独立变化的维度,且这两个维度都需要进行扩展,就是M x N问题,让M和N自己玩儿。

假如有这样的场景,有微信和支付宝等多种支付平台,同时又有人脸,指纹,密码等多种支付方式;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
public class PayController {
private Logger logger = LoggerFactory.getLogger(PayController.class);
public boolean doPay(String uId, String tradeId, BigDecimal amount, int channelType, int modeType) {
// 微信支付
if (1 == channelType) {
logger.info("模拟微信渠道支付划账开始。uId:{} tradeId:{} amount:{}", uId, tradeId, amount);
if (1 == modeType) {
logger.info("密码支付,风控校验环境安全");
} else if (2 == modeType) {
logger.info("人脸支付,风控校验脸部识别");
} else if (3 == modeType) {
logger.info("指纹支付,风控校验指纹信息");
}
}
// 支付宝支付
else if (2 == channelType) {
logger.info("模拟支付宝渠道支付划账开始。uId:{} tradeId:{} amount:{}", uId, tradeId, amount);
if (1 == modeType) {
logger.info("密码支付,风控校验环境安全");
} else if (2 == modeType) {
logger.info("人脸支付,风控校验脸部识别");
} else if (3 == modeType) {
logger.info("指纹支付,风控校验指纹信息");
}
}
return true;
}
}

虽然看起来已经满足了我们的不同支付类型和支付模式的组合,但是这样的代码在后面的维护以及扩展都会变得非常复杂,利用桥接模式就能很好解决问题。

支付类型桥接抽象类

1
2
3
4
5
6
7
8
9
10
11
public abstract class Pay {
protected Logger logger = LoggerFactory.getLogger(Pay.class);
protected IPayMode modeType;
public Pay(IPayMode modeType) {
this.modeType = modeType;
}
public abstract String transfer(String uId, String tradeId, BigDecimal amount);

微信支付

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class WxPay extends Pay {
public WxPay(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";
}
}

支付宝支付

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class ZfbPay extends Pay {
public ZfbPay(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";
}
}

支付模式接口

1
2
3
4
5
public interface IPayMode {
boolean security(String uId);
}

三种支付模式

刷脸

1
2
3
4
5
6
7
8
9
10
public class PayFaceMode implements IPayMode{
protected Logger logger = LoggerFactory.getLogger(PayCypher.class);
public boolean security(String uId) {
logger.info("人脸支付,风控校验脸部识别");
return true;
}
}

指纹

1
2
3
4
5
6
7
8
9
public class PayFingerprintMode implements IPayMode{
protected Logger logger = LoggerFactory.getLogger(PayCypher.class);
public boolean security(String uId) {
logger.info("指纹支付,风控校验指纹信息");
return true;
}
}

密码

1
2
3
4
5
6
7
8
9
10
public class PayCypher implements IPayMode{
protected Logger logger = LoggerFactory.getLogger(PayCypher.class);
public boolean security(String uId) {
logger.info("密码支付,风控校验环境安全");
return true;
}
}

编写测试类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class ApiTest {
@Test
public void test_pay() {
System.out.println("\r\n模拟测试场景;微信支付、人脸方式。");
Pay wxPay = new WxPay(new PayFaceMode());
wxPay.transfer("weixin_1092033111", "100000109893", new BigDecimal(100));
System.out.println("\r\n模拟测试场景;支付宝支付、指纹方式。");
Pay zfbPay = new ZfbPay(new PayFingerprintMode());
zfbPay.transfer("jlu19dlxo111","100000109894",new BigDecimal(100));
}
}
Luckylau wechat
如果对您有价值,看官可以打赏的!