java⽀付宝⽀付_重学Java设计模式:实战桥接模式(多⽀付
渠道与多⽀付模式)
沉淀、分享、成长,让⾃⼰和他⼈都能有所收获!
⼀、前⾔
为什么你的代码那么多ifelse
同类的业务、同样的功能,怎么就你能写出来那么多ifelse。很多时候⼀些刚刚从校园进⼊企业的萌新,或者⼀部分从⼩公司跳槽到⼤企业的程序员,初次承接业务需求的时候,往往编码还不成熟,经常⼀杆到底的写需求。初次实现确实很快,但是后期维护和扩展就⼗分痛苦。因为⼀段代码的可读性阅读他后期的维护成本也就越⾼。
设计模式是可以帮助你改善代码
冬天为什么起床困难很多时候你写出来的ifelse都是没有考虑使⽤设计模式优化,就像;同类服务的不同接⼝适配包装、同类物料不同组合的建造、多种奖品组合的营销⼯⼚等等。它们都可以让你代码中原本使⽤if判断的地⽅,变成⼀组组类和⾯向对象的实现过程。
怎么把设计模式和实际开发结合起来
多从实际场景思考,只到代码优化的最佳点,不要可以想着设计模式的使⽤。就像你最开始看设计
模式适合,因为没有真实的场景模拟案例,都是⼀些画圆形、⽅形,对新⼈或者理解能⼒还不到的伙伴来说很不友好。所以即使学了半天 ,但实际使⽤还是摸不着头脑。
⼆、开发环境
1. JDK 1.8
2. Idea + Maven
3. 涉及⼯程三个,可以通过关注:bugstack⾍洞栈,回复源码下载获取(打开获取的链接,到序号18)
⼯程描述itstack-demo-design-7-01使⽤⼀坨代码实现业务需求itstack-demo-design-7-02通过设计模式优化改造代码,产⽣对⽐性从⽽学习
三、桥接模式介绍
桥接模式的主要作⽤就是通过将抽象部分与实现部分分离,把多种可匹配的使⽤进⾏组合。说⽩了核⼼实现也就是在A类中含有B类接⼝,通过构造函数传递B类的实现,这个B类就是设计的桥。
那么这样的桥接模式,在我们平常的开发中有哪些场景
JDBC多种驱动程序的实现、同品牌类型的台式机和笔记本平板、业务实现中的多类接⼝同组过滤服
务等。这些场景都⽐较适合使⽤桥接模式进⾏实现,因为在⼀些组合中如果有如果每⼀个类都实现不同的服务可能会出现笛卡尔积,⽽使⽤桥接模式就可以⾮常简单。
四、案例场景模拟
随着市场的竞争在⽀付服务⾏业出现了和⽀付宝还包括⼀些其他⽀付服务,但是对于商家来说并不希望改变⽤户习惯。就像如果我的地摊只能使⽤或者只能使⽤⽀付宝付款,那么就会让我顾客伤⼼,鸡蛋灌饼也卖不动了。
在这个时候就出现了第三⽅平台,把市⾯上综合占据市场90%以上的⽀付服务都集中到⾃⼰平台中,再把这样的平台提供给店铺、超市、地摊使⽤,同时⽀持⼈脸、扫描、密码多种⽅式。
我们这个案例就模拟⼀个这样的第三⽅平台来承接各个⽀付能⼒,同时使⽤⾃家的⼈脸让⽤户⽀付起来更加容易。那么这⾥就出现了多⽀付与多模式的融合使⽤,如果给每⼀个⽀付都实现⼀次不同的模式,即使是继承类也需要开发好多。⽽且随着后⾯接⼊了更多的⽀付服务或者⽀付⽅式,就会呈爆炸似的扩展。
所以你现在可以思考⼀下这样的场景该如何实现?
五、⽤⼀坨坨代码实现
产品经理说⽼板要的需求,要尽快上,kpi你看着弄!
既然你逼我那就别怪我⽆情,还没有我⼀个类写不完的需求!反正写完就完事了,拿完绩效也要⾛了天天逼着写需求,代码越来越乱⼼疼后⾯的兄弟3秒。
1. ⼯程结构
资料员岗位职责itstack-demo-design-7-01└── src └── main └── java └── org.itstack.demo.design └── PayController.java
只有⼀个类⾥⾯都是ifelse,这个类实现了⽀付和模式的全部功能。
2. 代码实现
public class PayController { private Logger logger = Logger(PayController.class); public boolean doPay(String uId, String tradeId, Big
上⾯的类提供了⼀个⽀付服务功能,通过提供的必要字段;⽤户ID、交易ID、⾦额、渠道、模式,来控制⽀付⽅式。
以上的ifelse应该是最差的⼀种写法,即使写ifelse也是可以优化的⽅式去写的。
3. 测试验证
3.1 编写测试类
@Testpublic void test_pay() { PayController pay = new PayController(); System.out.println("模拟测试场景;⽀付、⼈脸⽅式。"); pay.doPay("weixin_109以上分别测试了两种不同的⽀付类型和⽀付模式;⼈脸⽀付、⽀付宝指纹⽀付
3.2 测试结果
模拟测试场景;⽀付、⼈脸⽅式。23:05:59.152 [main] INFO o.i.demo.design.pay.channel.Pay - 模拟渠道⽀付划账开始。uId:weixin_1092033111 tradeI 从测试结果看已经满⾜了我们的不同⽀付类型和⽀付模式的组合,但是这样的代码在后⾯的维护以及扩展都会变得⾮常复杂。
六、桥接模式重构代码
when you are gone歌词接下来使⽤桥接模式来进⾏代码优化,也算是⼀次很⼩的重构。
从上⾯的ifelse⽅式实现来看,这是两种不同类型的相互组合。那么就可以把⽀付⽅式和⽀付模式进⾏分离通过抽象类依赖实现类的⽅式进
⾏桥接,通过这样的拆分后⽀付与模式其实是可以单独使⽤的,当需要组合时候只需要把模式传递给⽀付即可。
桥接模式的关键是选择的桥接点拆分,是否可以到这样类似的相互组合,如果没有就不必要⾮得使⽤桥接模式。
1. ⼯程结构
itstack-demo-design-7-02└── src ├── main │└── java │└── org.itstack.demo.design.pay │├── channel ││├── Pay.java ││桥接模式模型结构
如何购买基金新手计算机实习报告范文左侧Pay是⼀个抽象类,往下是它的两个⽀付类型实现;⽀付、⽀付宝⽀付。
右侧IPayMode是⼀个接⼝,往下是它的两个⽀付模型;刷脸⽀付、指纹⽀付。
那么,⽀付类型 × ⽀付模型 = 就可以得到相应的组合。
注意,每种⽀付⽅式的不同,刷脸和指纹校验逻辑也有差异,可以使⽤适配器模式进⾏处理,这⾥不是本⽂重点不做介绍,可以看适配器模式章节。
2. 代码实现
2.1 ⽀付类型桥接抽象类
public abstract class Pay { protected Logger logger = Logger(Pay.class); protected IPayMode payMode; public Pay(IPayMode pay
在这个类中定义了⽀付⽅式的需要实现的划账接⼝:transfer,以及桥接接⼝;IPayMode,并在构造函数中⽤户⽅⾃⾏选择⽀付⽅式。
如果没有接触过此类实现,可以重点关注 IPayMode payMode,这部分是桥接的核⼼。
2.2 两个⽀付类型的实现
⽀付
public class WxPay extends Pay { public WxPay(IPayMode payMode) { super(payMode); } public String transfer(String uId, String tradeId, BigDe ⽀付宝⽀付
public class ZfbPay extends Pay { public ZfbPay(IPayMode payMode) { super(payMode); } public String transfer(String uId, String tradeId, BigDe
这⾥分别模拟了调⽤第三⽅的两个⽀付渠道;、⽀付宝,当然作为⽀付综合平台可能不只是接了这两个渠道,还会有其很跟多渠道。
另外可以看到在⽀付的时候分别都调⽤了风控的接⼝进⾏验证,也就是不同模式的⽀付(刷脸、指纹),都需要过指定的风控,才能保证⽀付安全。
2.3 定义⽀付模式接⼝
public interface IPayMode { boolean security(String uId);}
任何⼀个⽀付模式;刷脸、指纹、密码,都会过不同程度的安全风控,这⾥定义⼀个安全校验接⼝。
2.4 三种⽀付模式风控(刷脸、指纹、密码)
刷脸
public class PayFaceMode implements IPayMode{ protected Logger logger = Logger(PayCypher.class); public boolean security(Stri 指纹
public class PayFingerprintMode implements IPayMode{ protected Logger logger = Logger(PayCypher.class); public boolean securi 密码
public class PayCypher implements IPayMode{ protected Logger logger = Logger(PayCypher.class); public boolean security(String
汽车套子在这⾥实现了三种⽀付模式(刷脸、指纹、密码)的风控校验,在⽤户选择不同⽀付类型的时候,则会进⾏相应的风控拦截以此保障⽀付安全。
3. 测试验证
3.1 编写测试类
@Testpublic void test_pay() { System.out.println("模拟测试场景;⽀付、⼈脸⽅式。"); Pay wxPay = new WxPay(new PayFaceMode()); ansfer("
与上⾯的ifelse实现⽅式相⽐,这⾥的调⽤⽅式变得整洁、⼲净、易使⽤;new WxPay(new PayFaceMode())、new ZfbPay(new
PayFingerprintMode())
外部的使⽤接⼝的⽤户不需要关⼼具体的实现,只按需选择使⽤即可。
⽬前以上优化主要针对桥接模式的使⽤进⾏重构if逻辑部分,关于调⽤部分可以使⽤抽象⼯⼚或策略模式配合map结构,将服务配置
化。因为这⾥主要展⽰桥接模式,所以就不在额外多加代码,避免喧宾夺主。
3.2 测试结果
模拟测试场景;⽀付、⼈脸⽅式。23:14:40.911 [main] INFO o.i.demo.design.pay.channel.Pay - 模拟渠道⽀付划账开始。uId:weixin_1092033111 tradeI 从测试结果看内容是⼀样的,但是整体的实现⽅式有了很⼤的变化。所以有时候不能只看结果,也要看看过程
七、总结
通过模拟与⽀付宝两个⽀付渠道在不同的⽀付模式下,刷脸、指纹、密码,的组合从⽽体现了桥接模式的在这类场景中的合理运
⽤。简化了代码的开发,给后续的需求迭代增加了很好的扩展性。
从桥接模式的实现形式来看满⾜了单⼀职责和开闭原则,让每⼀部分内容都很清晰易于维护和拓展,但如果我们是实现的⾼内聚的代
码,那么就会很复杂。所以在选择重构代码的时候,需要考虑好整体的设计,否则选不到合理的设计模式,将会让代码变得难以开发。
任何⼀种设计模式的选择和使⽤都应该遵顼符合场景为主,不要刻意使⽤。⽽且统⼀场景因为业务的复杂从⽽可能需要使⽤到多种设计模式的组合,才能将代码设计的更加合理。但这种经验需要从实际的项⽬中学习经验,并提不断的运⽤。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论