父文章[理论]领域驱动设计 DDD 是啥,cqrs是啥_个人渣记录仅为自己搜索用的博客-CSDN博客_cqrs ddd
子文章 代码结构-可维护性代码_fei33423的专栏-CSDN博客
子文章 如何梳理和重构 含复杂性度量_个人渣记录仅为自己搜索用的博客-CSDN博客
1. 封装.
现在的理解 就领域实体里的字段越来越少. 之前的理解 就是越上层参数越少.
2. 同字段不同领域对象
3. 组合大于继承/回调/spi , 平台大于中台
只有很稳定了,且回调的节点概念不业务化
ddd优雅应用
电话号码,银行卡号脱敏打印. 把这些属性对象化,在toString里设置脱敏打印.
案例:
ddddemo: 一个sofa demo 实现了领域驱动设计 - Gitee.com 使用了spring 的 scope理念, sofa的分层osgi隔离,很好的实现了数据库表entity和领域层bean的隔离. 其中一个区别就是:
1.1 领域层bean都是枚举类 , 封装类,例如上面的电话号码类 1.2. 数据库层就是普通的拉平的int,string.
from DDD 是啥,cqrs是啥
2.边界,考虑是否该关心变化. 边界可能需要记录流水. 行为也是实体.
kpay和paygateway. 支付渠道的新增不应该改变kuaipay的重启. 对于透传的参数底层提供者要封装自己的if else. 不能拆分开.
现在支付宝h5和支付宝sdk 网关提供不同的接口,导致每次新增kuaipay都要变动.
3.实体类型:
真的实体(产品角度),行为实体(产品觉得是一个阶段,但在技术实现,流程是分多个阶段的,异步实现.行为也变成了实体.)
log实体(网关层)
4.对于update的永远不要返回值,仅需要返回errorCode(java实现时 返回void,通过throwException实现, errCodeStr是个泛化的返回值,含有各种情况.)
6.对于get后的nullPoint不需要考虑.除非明确的业务需求,或者允许为null.不一定要校验抛exception.
7.避免业务映射,采用业务定义的方式.
举例:
有个bizType用来记录对应的第三方支付帐户(不同渠道有不同的帐户)
缺少一个subChannelId子类型的字段,业务定义.目前是通过业务映射来实现.不能通过无穷尽的字段进行业务映射.
//通过业务映射,需要定义一个子渠道的字段.
if (xx.getBizType().intValue() == BizType.WAllet.getCode().intValue()||xx.getBizType().intValue() == BizType.xxx_WALLET.getCode().intValue()) {
return doWithAlipayWappay(prePayDO);
}else{
调用其他.
}
举例二: 主类型,子类型. 产品有时候只关心主类型. 各种统计都是group by 什么的. 如果没有主类型字段,每次增加新的子类型,各种统计都要跟上去.
8. 透传字段全封装成JsonString. 这样就不会出现透传字段增加值影响中间系统变更的问题.
产品都是从流程的角度去思考
好的代码应该是从对象的角度去思考.
举例: 微信支付,支付宝支付,企业支付.
都有支付,退款,提现,回调,主动查询等流程.
做的比较好是设计一个共用接口,微信,支付宝,企业等实现他.
框架用接口来写.就简单很多了.
但有个难点: 每个对象处理业务时需要的数据对象是不同的,框架如何做出适配?
1. 全程用Object
2. 用泛型
3. 用存储对象的id,接口传递中用相同的long即可,其他细节数据,在各自操作中实现.
支付接口
内含支付,回调,查询,退款,退款查询,退款回调
提现接口:
提现,回调,查询