✨这里是第七人格的博客✨小七,欢迎您的到来~✨
🍅系列专栏:设计模式🍅
✈️本篇内容:桥接模式✈️
🍱本篇收录完整代码地址:gitee.com/diqirenge/d...🍱
楔子
小七才上高一的时候,成绩还可以,就算每天不做作业,也跟得上老师上课的进度,甚至还可以在考试的时候玩玩控分。可是到了高二,小七才慢慢发现,自己想考好也考不出高分了,现在想来有很大部分原因就是由于长时间缺少练习导致的。编程学习又何尝不是如此呢?
需求背景
假设我们有一个在线商城,支持多种支付方式(如支付宝、微信支付等)和支付模式(如实时支付、预授权支付等)。
每一种支付方式都有多种支付模式,而每一种支付模式也可以用到多种支付方式上。现在让你设计对接这个支付功能。
分析设计
稍微想一想,支付模式和支付方式是两种不同类型的相互组合,所以我们将抽象部分(支付方式)与它的实现部分(支付模式)分离,将实现部分抽象成单独的类,使它们都可以独立地变化。可以将支付模式看作支付方式的一个属性,进行桥接。
UML图
根据分析设计,我们可以先画一个简单的UML图,后面通过UML图编码
整个类图看起来像一座桥,所以称为桥接模式。
模块名称
bridge
模块地址
模块描述
桥接模式代码示例
代码实现
1、抽象支付方式
java
/**
* 桥接模式 - 抽象支付方式
* 关注公众号【奔跑的码畜】,一起进步不迷路
*
* @author 第七人格
* @date 2023/11/29
*/
public abstract class Pay {
/**
* 通过抽象类依赖实现类的⽅式进⾏桥接
*/
protected IPayMode payMode;
/**
* setPayment这个方法只是一种对象的传递方式,当然你也可以使用构造方法传递。
*
* @param payMode
*/
public void setPayMode(IPayMode payMode) {
this.payMode = payMode;
}
public abstract void pay();
}
注:setPayment这个方法只是一种对象的传递方式,当然你也可以使用构造方法传递。
具体实现子类-支付宝支付方式
java
/**
* 桥接模式 - 具体实现子类-支付宝支付方式
* 关注公众号【奔跑的码畜】,一起进步不迷路
*
* @author 第七人格
* @date 2023/11/29
*/
public class AliPay extends Pay {
@Override
public void pay() {
payMode.checkAccount();
System.out.println("调用支付宝支付成功!");
}
}
具体实现子类-微信支付方式
java
/**
* 桥接模式 - 具体实现子类-微信支付方式
* 关注公众号【奔跑的码畜】,一起进步不迷路
*
* @author 第七人格
* @date 2023/11/29
*/
public class WeChatPay extends Pay {
@Override
public void pay() {
payMode.checkAccount();
System.out.println("调用微信支付成功!");
}
}
2、抽象支付模式
一般支付前会调用风控系统,我们这里简单的校验一下账户就可以了
java
/**
* 桥接模式 - 抽象支付模式
* 关注公众号【奔跑的码畜】,一起进步不迷路
*
* @author 第七人格
* @date 2023/11/29
*/
public interface IPayMode {
boolean checkAccount();
String name();
}
具体实现子类-预授权支付模式
java
/**
* 桥接模式 - 具体实现子类-预授权支付模式
* 关注公众号【奔跑的码畜】,一起进步不迷路
*
* @author 第七人格
* @date 2023/11/29
*/
public class PreAuthMode implements IPayMode {
@Override
public boolean checkAccount() {
System.out.println(this.name() + "-" +"校验账户是否有效");
return false;
}
@Override
public String name() {
return "预授权支付模式";
}
}
具体实现子类-实时支付模式
java
/**
* 桥接模式 - 具体实现子类-实时支付模式
* 关注公众号【奔跑的码畜】,一起进步不迷路
*
* @author 第七人格
* @date 2023/11/29
*/
public class RealTimeMode implements IPayMode {
@Override
public boolean checkAccount() {
System.out.println(this.name() + "-" +"校验账户是否有效");
return false;
}
@Override
public String name() {
return "实时支付模式";
}
}
3、编写工厂模块
为了方便创建对象,我们可以用到前面学习过的工厂模式
java
/**
* 工厂模式 - 创建Pay对象
* 关注公众号【奔跑的码畜】,一起进步不迷路
*
* @author 第七人格
* @date 2023/11/29
*/
public class PayFactory {
private PayFactory() {
}
public static Pay createPay(String type, String mode) {
if (type.equalsIgnoreCase("alipay")) {
AliPay aliPay = new AliPay();
if (mode.equalsIgnoreCase("pre_auth")) {
aliPay.setPayMode(new PreAuthMode());
} else if (mode.equalsIgnoreCase("real_time")) {
aliPay.setPayMode(new RealTimeMode());
} else {
throw new IllegalArgumentException("Invalid payment type: " + type);
}
return aliPay;
} else if (type.equalsIgnoreCase("wechat_pay")) {
WeChatPay weChatPay = new WeChatPay();
if (mode.equalsIgnoreCase("pre_auth")) {
weChatPay.setPayMode(new PreAuthMode());
} else if (mode.equalsIgnoreCase("real_time")) {
weChatPay.setPayMode(new RealTimeMode());
} else {
throw new IllegalArgumentException("Invalid payment type: " + type);
}
return weChatPay;
} else {
throw new IllegalArgumentException("Invalid payment type: " + type);
}
}
}
4、编写测试类
java
/**
* 测试桥接模式
* 关注公众号【奔跑的码畜】,一起进步不迷路
*
* @author 第七人格
* @date 2023/11/29
*/
public class BridgeTest {
@Test
public void testBridge() {
System.out.println("======alipay,real_time======");
Pay pay = PayFactory.createPay("alipay", "real_time");
pay.pay();
System.out.println("\n======alipay,pre_auth======");
Pay pay2 = PayFactory.createPay("alipay", "pre_auth");
pay2.pay();
System.out.println("\n======wechat_pay,real_time======");
Pay pay3 = PayFactory.createPay("wechat_pay", "real_time");
pay3.pay();
System.out.println("\n======wechat_pay,pre_auth======");
Pay pay4 = PayFactory.createPay("wechat_pay", "pre_auth");
pay4.pay();
}
}
5、测试结果
======alipay,real_time======
实时支付模式-校验账户是否有效
调用支付宝支付成功!
======alipay,pre_auth======预授权支付模式-校验账户是否有效
调用支付宝支付成功!
======wechat_pay,real_time======实时支付模式-校验账户是否有效
调用微信支付成功!
======wechat_pay,pre_auth======预授权支付模式-校验账户是否有效
调用微信支付成功!
实现要点
再回忆一下这个URL图
1、选择的桥接点拆分
例子中为:支付模式
2、定义抽象类和实现类
3、桥接在一起
例子中为:工厂调用set方法进行桥接
你也可以使用构造方法传递的方式
总结
桥接模式是一种结构型设计模式,它将抽象与实现解耦,使得两者可以独立地变化。从桥接模式的设计上我们可以看出聚合是一种比继承要弱的关联关系,支付方式和支付模式都可独立的进行变化,不会互相影响。