目录
2.2.2.3.1 支付模式IPayMode接口 (实现化角色)
桥接模式(bridge pattern) 的定义是:将抽象部分与它的实现部分分离,使它们都可以独立地变化。
桥接模式用一种巧妙的方式处理多层继承存在的问题,用抽象关联来取代传统的多层继承,将类之间的静态继承关系转变为动态的组合关系,使得系统更加灵活,并易于扩展,有效的控制了系统中类的个数 (避免了继承层次的指数级爆炸)。
桥接(Bridge)模式包含以下主要角色:
桥接模式原理的核心是:首先有要识别出一个类所具有的的两个独立变化维度,将它们设计为两个独立的继承等级结构,为两个维度都提供抽象层,并建立抽象耦合。总结一句话就是:抽象角色引用实现角色
比如我们拿毛笔举例,型号和颜色是毛笔的两个维度型号是其固有的维度,所以抽象出一个毛笔类,而将各种型号的毛笔作为其子类,也就是下图的右侧抽象部分内容.颜色是毛笔的另一个维度,它与毛笔之间存在一种设置的关系,因此可以提供一个抽象的颜色接口,将具体颜色作为该接口的子类。
模拟不同的支付工具对应不同的支付模式,比如微信和支付宝都可以完成支付操作,而支付操作又可以有扫码支付、密码支付、人脸支付等,那么关于支付操作其实就有两个维度,包括:支付渠道和支付方式。
package main.java.cn.test.bridge.V1;
import java.math.BigDecimal;
/**
* @author ningzhaosheng
* @date 2024/1/12 17:48:33
* @description 不使用设计模式实现
*/
public class PayController {
/**
* @param uId 用户id
* @param tradeId 交易流水号
* @param amount 交易金额
* @param channelType 渠道类型 1 微信, 2 支付宝
* @param modeType 支付模式 1 密码,2 人脸,3 指纹
* @return: boolean
*/
public boolean doPay(String uId, String tradeId, BigDecimal amount, int channelType, int modeType) {
//微信支付
if (1 == channelType) {
System.out.println("微信渠道支付划账开始......");
if (1 == modeType) {
System.out.println("密码支付");
}
if (2 == modeType) {
System.out.println("人脸支付");
}
if (3 == modeType) {
System.out.println("指纹支付");
}
}
//支付宝支付
if (2 == channelType) {
System.out.println("支付宝渠道支付划账开始......");
if (1 == modeType) {
System.out.println("密码支付");
}
if (2 == modeType) {
System.out.println("人脸支付");
}
if (3 == modeType) {
System.out.println("指纹支付");
}
}
return true;
}
}
package main.java.cn.test.bridge.V1;
import java.math.BigDecimal;
/**
* @author ningzhaosheng
* @date 2024/1/12 17:50:07
* @description 测试方法
*/
public class Test_Pay {
public static void main(String[] args) {
PayController payController = new PayController();
System.out.println("测试: 微信支付、人脸支付方式");
payController.doPay("weixin_001", "1000112333333", new
BigDecimal(100), 1, 2);
System.out.println("\n测试: 支付宝支付、指纹支付方式");
payController.doPay("hifubao_002", "1000112334567", new
BigDecimal(100), 2, 3);
}
}
从测试结果看,是满足了需求,但是这样的代码设计,后面的维护和扩展都会变得非常复杂。
桥接模式原理的核心是:首先有要识别出一个类所具有的的两个独立变化维度,将它们设计为两个独立的继承等级结构,为两个维度都提供抽象层,并建立抽象耦合。
? 支付渠道子类: 微信支付
? 支付渠道子类: 支付宝支付
? 支付模式实现: 刷脸支付
? 支付模式实现: 指纹支付
package main.java.cn.test.bridge.V2;
/**
* @author ningzhaosheng
* @date 2024/1/12 17:57:53
* @description 支付模式接口
*/
public interface IPayMode {
//安全校验功能: 对各种支付模式进行风控校验
boolean security(String uId);
}
package main.java.cn.test.bridge.V2;
/**
* @author ningzhaosheng
* @date 2024/1/12 18:01:14
* @description 密码支付及风控校验
*/
public class PayCypher implements IPayMode {
@Override
public boolean security(String uId) {
System.out.println("密码支付,风控校验-环境安全");
return false;
}
}
package main.java.cn.test.bridge.V2;
/**
* @author ningzhaosheng
* @date 2024/1/12 18:00:30
* @description 刷脸支付及风控校验
*/
public class PayFaceMode implements IPayMode {
@Override
public boolean security(String uId) {
System.out.println("人脸支付,风控校验-脸部识别");
return true;
}
}
package main.java.cn.test.bridge.V2;
/**
* @author ningzhaosheng
* @date 2024/1/12 17:59:33
* @description 指纹支付及风控校验
*/
public class PayFingerprintMode implements IPayMode {
@Override
public boolean security(String uId) {
System.out.println("指纹支付,风控校验-指纹信息");
return true;
}
}
package main.java.cn.test.bridge.V2;
import java.math.BigDecimal;
/**
* @author ningzhaosheng
* @date 2024/1/12 18:02:02
* @description 支付抽象类
*/
public abstract class Pay {
//桥接对象
protected IPayMode payMode;
public Pay(IPayMode payMode) {
this.payMode = payMode;
}
//划账功能
public abstract String transfer(String uId, String
tradeId, BigDecimal amount);
}
package main.java.cn.test.bridge.V2;
import java.math.BigDecimal;
/**
* @author ningzhaosheng
* @date 2024/1/12 18:02:59
* @description 支付渠道-微信划账
*/
public class WxPay extends Pay {
public WxPay(IPayMode payMode) {
super(payMode);
}
@Override
public 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";
}
}
package main.java.cn.test.bridge.V2;
import java.math.BigDecimal;
/**
* @author ningzhaosheng
* @date 2024/1/12 18:04:46
* @description 支付渠道-支付宝划账
*/
public class ZfbPay extends Pay {
public ZfbPay(IPayMode payMode) {
super(payMode);
}
@Override
public 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";
}
}
package main.java.cn.test.bridge.V2;
import java.math.BigDecimal;
/**
* @author ningzhaosheng
* @date 2024/1/12 18:06:15
* @description 测试
*/
public class Test_Pay {
public static void main(String[] args) {
System.out.println("测试场景1: 微信支付、人脸方式.");
Pay wxpay = new WxPay(new PayFaceMode());
wxpay.transfer("wx_00100100", "10001900", new BigDecimal(100));
System.out.println();
System.out.println("测试场景2: 支付宝支付、指纹方式");
Pay zfbPay = new ZfbPay(new PayFingerprintMode());
zfbPay.transfer("jlu1234567", "567689999999", new BigDecimal(200));
}
}
代码重构完成后,结构更加清晰整洁,可读性和易用性更高,外部的使用接口的用户不需要关心具体实现。桥接模式满足了单一职责原则和开闭原则,让每一部分都更加清晰并且易扩展。
好了,本次分享就到这里,欢迎大家继续阅读《设计模式》专栏其他设计模式内容,如果有帮助到大家,欢迎大家点赞+关注+收藏,有疑问也欢迎大家评论留言!