对账单格式
前面三篇文章讲了代理模式、桥接模式、装饰器模式,这次讲一下适配器模式。
适配器模式比较简单,也比较容易理解。适配器模式可以看作一种“补偿模式”,用来补救设计上的缺陷。应用这种模式算是“无奈之举”。
UML类图位置:https://www.processon.com/diagraming/609b375407912943913a4c13
本文代码链接为:https://github.com/shidawuhen/asap/blob/master/controller/design/14adapter.go
1.定义1.1适配器模式适配器模式:将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
UML:
1.2分析通过UML图看到Adapter和Adaptee是关联关系,但Adapter和Adaptee也可以是继承关系,这种情况一般用于Adaptee大部分成员函数已经和Target一致,只有少部分需要修改,使用继承能够减少代码改动。如果Adaptee大部分成员函数和Target不一致,最好还是用组合,毕竟组合优于继承。当然对Go而言就无所谓了,反正只有组合没有继承,而且匿名组合能够直接复用组合对象的功能。
适配器模式的使用也比较简单,核心就是用Adapter重新封装一下Adaptee,使其符合Target的要求。
2.使用场景遇到如下几种场景的时候可以考虑使用适配器模式:
封装有缺陷的接口设计:例如如果引入的外部系统接口设计方面有缺陷,会影响我们自身代码的可测性等,就可以考虑使用适配器模式,将引入的系统向我们自身系统设计上靠拢
统一多个类的接口设计:如果一个功能依赖多个外部系统,且这些外部系统的能力是相似的但接口不统一,可以使用适配器模式,依赖于继承、多态的特性,使调用方可以以聚合方式使用外部系统,提升代码扩展性
替换依赖的外部系统:如果一个功能有多个外部系统可供选择,我们可以定义一个Target接口,将外部系统适配为Target,这样就能利用多态性,实现外部系统的替换
兼容老版本接口:老版本中功能A在新版本中被废弃,A将由B替代,为了不影响使用者,新版本中仍然会有A,但是其内部实现委托B执行
适配不同格式的数据:有时数据来源不同,数据格式也不同,需要对数据做适配,改为统一格式后再处理,也可使用适配器模式
我在项目中用适配器模式,主要处理数据适配。以前做支付网关的时候,每个第三方返回的数据都不一致,为了符合支付系统定义的格式,必须进行适配。这种地方特别多,就选对账功能这块讲一下,其它关于支付的内容可以参考这篇文章如何高效对接第三方支付。
3.代码实现所谓对账,是指从第三方支付公司拉取指定时间内的支付单信息,与系统内部支付单信息做对比,主要用来发现支付异常
支付网关有数据,第三方没有数据
可能被黑客攻击了,用户没有真正支付,但是我们发货了
代码有问题,用户没有完成支付,但是系统认为支付成功了
第三方提供数据不全
支付网关没有数据,第三方有数据
用户支付成功,但是同步或者异步通知都失败了
金额不一致
代码有问题,电商发起支付金额和真正调用第三方金额不一致
第三方提供数据有问题
做对比的逻辑是一致的,但是第三方支付账单数据格式不一致,所以需要先将这些数据转化为标准格式。
package main
import (
“fmt”
“time”
/**
* @Description: 对账单数据
type StatementItem struct {
string //系统单号
string //第三方交易号
int64 //支付金额,单位:分
int64 //订单支付时间
/**
* @Description: 从第三方获取对账数据
type StatementData interface {
int64, endTime int64) []*StatementItem
/**
* @Description: WX支付
type WXStatementData struct {
func (w *WXStatementData) GetStatementData(startTime int64, endTime int64) []*StatementItem {
“从WX获取到的对账数据,支付时间需要格式化为时间戳”)
return []*StatementItem{
OrderId: “WX订单222”,
“WX支付单号”,
999,
2014, 1, 7, 5, 50, 4, 0, time.Local).Unix(),
}
/**
* @Description: ZFB支付
type ZFBStatementData struct {
func (z *ZFBStatementData) GetStatementData(startTime int64, endTime int64) []*StatementItem {
“从ZFB获取到的对账数据,金额需要从元转化为分”)
return []*StatementItem{
OrderId: “ZFB订单111”,
“ZFB支付单号”,
99.9 * 100,
1389058332,
}
/**
* @Description: 对账函数
* @return bool
func DoStatement(list []*StatementItem) bool {
“开始对账”)
“从自身系统中获取指定时间内的支付单”)
for _, item := range list {
” 与系统支付单进行对账”)
fmt.Println(“对账完成”)
return true
func main() {
zfb := &ZFBStatementData{}
wx,
}
for _, s := range stattementData {
1389058332, 1389098332))
}
输出:
? myproject go run main.go
从WX获取到的对账数据,支付时间需要格式化为时间戳
开始对账
从自身系统中获取指定时间内的支付单
WX订单222 与系统支付单进行对账
对账完成
从ZFB获取到的对账数据,金额需要从元转化为分
开始对账
从自身系统中获取指定时间内的支付单
ZFB订单111 与系统支付单进行对账
对账完成
PS:代码中定义了对账单的结构,今后对接新的支付方式,只要实现了StatementData接口,就能参与对账,扩展性极好。
总结适配器模式简单好用,用对了场景能够极大提高扩展性和优雅性。
适配器模式和代理、装饰器、桥接模式有一定相似性,我们在此处也总结一下:
代理模式: 代理模式在不改变原始类接口的条件下,为原始类定义一个代理类,主要目的是控制访问,而非加强功能,这是它跟装饰器模式最大的不同。
装饰器模式: 装饰者模式在不改变原始类接口的情况下,对原始类功能进行增强,并且支持多个装饰器的嵌套使用。
适配器模式: 适配器模式是一种事后的补救策略。适配器提供跟原始类不同的接口,而代理模式、装饰器模式提供的都是跟原始类相同的接口。
桥接模式: 桥接模式的目的是将接口部分和实现部分分离,从而让它们可以较为容易、也相对独立地加以改变。
最后大家如果喜欢我的文章,可以关注我的公众号(程序员麻辣烫)
我的个人博客为:https://shidawuhen.github.io/
往期文章回顾:
招聘
字节跳动|内推大放送
字节跳动|今日头条广州服务端研发工程师内推
字节跳动|抖音电商急招上海前端开发工程
字节跳动|抖音电商上海资深服务端开发工程师-交易
字节跳动|抖音电商武汉服务端(高级)开发工程师
字节跳动|飞书大客户产品经理内推咯
字节跳动|抖音电商服务端技术岗位虚位以待
字节跳动招聘专题
设计模式
Go设计模式(13)-装饰器模式
Go设计模式(12)-桥接模式
Go设计模式(11)-代理模式
Go设计模式(10)-原型模式
Go设计模式(9)-建造者模式
Go设计模式(8)-抽象工厂
Go设计模式(7)-工厂模式
Go设计模式(6)-单例模式
Go设计模式(5)-类图符号表示法
Go设计模式(4)-代码编写优化
Go设计模式(4)-代码编写
Go设计模式(3)-设计原则
Go设计模式(2)-面向对象分析与设计
Go设计模式(1)-语法
语言
再也不怕获取不到Gin请求数据了
一文搞懂pprof
Go工具之generate
Go单例实现方案
Go通道实现原理
Go定时器实现原理
Beego框架使用
Golang源码BUG追查
Gin框架简洁版
Gin源码剖析
架构
分页复选设计的坑
支付接入常规问题
限流实现2
秒杀系统
分布式系统与一致性协议
微服务之服务框架和注册中心
浅谈微服务
限流实现1
CDN请求过程详解
常用缓存技巧
如何高效对接第三方支付
算法总结
存储
MySQL开发规范
Redis实现分布式锁
事务原子性、一致性、持久性的实现原理
InnoDB锁与事务简析
网络
HTTP2.0基础教程
HTTPS配置实战
HTTPS连接过程
TCP性能优化
工具
GoLand实用技巧
根据mysql表自动生成go struct
Markdown编辑器推荐-typora
读书笔记
《毛选》推荐
原则
资治通鉴
敏捷革命
如何锻炼自己的记忆力
简单的逻辑学-读后感
热风-读后感
论语-读后感
孙子兵法-读后感
思考
为动员一切力量争取胜利而斗争
反对自由主义
实践论
评价自己的标准
服务端团队假期值班方案
项目流程管理
对项目管理的一些看法
对产品经理的一些思考
关于程序员职业发展的思考
关于代码review的思考
对账单格式(Go设计模式(14)-适配器模式)
相关推荐
- 高考模式3+2+1是什么意思(高中选科3+2+1最佳方案)
- 专业模式拍照参数介绍(专业模式各个功能简介)
- 手机的飞行模式是什么意思 华为手机的飞行模式
- 小米性能模式有什么用(红米开性能模式区别大吗)
- 振动模式用英语怎么说 振动模式的作用
- 鸣人仙人模式出场是哪一集(火影忍者鸣人仙人模式登场)
- 安全模式怎么关闭(vivo手机怎么关安全模式)
- 苹果怎么静音模式不震动(苹果怎么静音模式震动)
- 步数计步器(ZeppLife刷步接口)
- se怎么退出dfu模式(iphonese怎么进入dfu模式)
- 如何通过控制中心在 iPhone 上快速开启低电量模式
- oppo reno深色模式如何设置(opporenoz怎么设置深色模式)
- 苹果电脑usb接口没反应怎么办(苹果电脑usb接口全部失灵)
- macos安全模式修复(macos安全性更新有必要吗)
- 如何以安全模式启动windows或苹果mac电脑(mac怎么以安全模式启动)
- windows11上如何开启上帝模式并激活详细教程!(win10开启上帝模式)