View Code? Open in Web Editor
NEW
本代码库为码如云后端代码。码如云是一个基于二维码的一物一码管理平台,可以为每一件“物品”生成一个二维码,手机扫码即可查看物品信息并发起相关业务操作,操作内容可由你自己定义,典型的应用场景包括固定资产管理、设备巡检以及物品标签等。在技术上,码如云是一个无代码平台,全程采用DDD、整洁架构和事件驱动架构**完成开发。
Home Page: https://www.mryqr.com
License: GNU General Public License v3.0
Shell 0.01%
JavaScript 0.01%
Java 99.99%
mry-backend's People
Contributors
Watchers
mry-backend's Issues
消息队列有没有kafka的实现代码,请开源一份,多谢
看了关于DDD的系列文章和代码,深受启发,但还有几个疑问想要请教:
1.涉及多个聚合的操作,使用领域事件还是将逻辑在应用服务中编排?从代码上看,貌似区别仅在于多个聚合操作是否在同一个事务下?
2.代码中的RepeatableTask和OnetimeTask两个Marker接口,没发现其实际的作用,其设计意图是什么呢?
3.2中的两个接口,在注释中有这样的描述:'保证一个Task只做一件事情,即只操作一种聚合',但看代码中貌似并没有严格遵循这个约定,如SyncOrderToManagedQrTask中,操作了QR、Submission等聚合,这里的设计考虑是什么呢?
看了作者的DDD实践,收获很多,我们项目也借鉴了本项目来落地,过程中结合自己团队实际优化了不少细节,但是也有很多疑惑,希望有个群,感兴趣的人可以共同探讨!
仔细阅读了您的码如云的后端代码以及DDD的相关文章,也阅读了许多DDD的相关文章,关于聚合根创建参数特别多(比如创建聚合根需要10个以上的参数)没有找到一个统一的解决方案。目前看到有的项目直接将command作为值对象放在领域层;有的直接在聚合根构造函数或聚合根创建工厂直接列举所有参数(这种方式对于参数比较少还比较合适);有的直接向领域层直接聚合根构造函数或者聚合根创建工厂传递应用层XXXCreateComand(这种方式感觉有些偷懒不是很优雅,造成应用层和领域层高度耦合),关于这个问题向作者请教,有没有好的建议或者解决方式。
举例如下,码如云代码中member在构造工厂中创建
![image](https://private-user-images.githubusercontent.com/10722542/271746511-4d9904ad-5226-4929-adea-2ab7502a4f8a.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MTg5Nzg4ODMsIm5iZiI6MTcxODk3ODU4MywicGF0aCI6Ii8xMDcyMjU0Mi8yNzE3NDY1MTEtNGQ5OTA0YWQtNTIyNi00OTI5LWFkZWEtMmFiNzUwMmE0ZjhhLnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNDA2MjElMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjQwNjIxVDE0MDMwM1omWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTY1YTdmZTFlZjg2ZjZkZDhiMzgzODlkOThhODM5NjQ1MWY3MjE3ODMxMjcwZjRiODkyZGI3ZjcwOTQyNDQzYTImWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JmFjdG9yX2lkPTAma2V5X2lkPTAmcmVwb19pZD0wIn0.2uqEc2CxlsYbjUg2zfD6NOa0O0e8aRhx21mpXXfHmHk)
此时构造工厂创建方法参数已经达到7个,如果后续创建场景变化参数更多,那么直接将参数罗列在方法入参内对调用方也会造成一定的困扰甚至灾难。
考虑一个转账的逻辑,分为一下几步:
1)查询数据库检查重入 -- 领域层的仓储接口
2)若未重入初始一个订单(实体) -- 通过领域层的工厂方法/实体构造方法/或者领域服务函数
3)将订单实体存入数据库 -- 领域层的仓储接口
4)调用外部转账接口 -- 领域层定义的适配器接口
5)调用实体或者领域服务方法验证结果 -- 领域层中实体的方法或者领域服务中的函数实现
6)将转账结果回写数据库 -- 领域层的仓储接口
我的想法是在应用层编排上面6个步骤,而上面6个步骤都在领域层以小个小个的单元实现。但总感觉编排6个步骤其实也是业务逻辑,1)、2)、3)可以合并成一个初始化订单领域服务函数,他们之间甚至是有因果关系;5)和6)也可以合并未一个存储转账结果的领域服务函数。请问应该如何区分领域服务和应用服务,求经验分享☺️☺️☺️☺️
首先对作者表达感谢,因为市面上真正落地且开源的DDD项目少得可怜,感谢作者开发了码如云项目为我们提供了一个DDD讨论之所。
我的问题是资源层除了返回聚合根,是否还能返回非聚合根?因为在这篇文章中,作者提到“资源库方法所接受的参数和返回的数据都应该是聚合根对象是返回聚合根”,但是查看代码却发现非聚合根也被返回了,这是否有冲突?
![image](https://private-user-images.githubusercontent.com/26236775/277551285-42d2721f-60ee-4f6b-a733-734fe79a872f.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MjEzMDAyNjQsIm5iZiI6MTcyMTI5OTk2NCwicGF0aCI6Ii8yNjIzNjc3NS8yNzc1NTEyODUtNDJkMjcyMWYtNjBlZS00ZjZiLWE3MzMtNzM0ZmU3OWE4NzJmLnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNDA3MTglMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjQwNzE4VDEwNTI0NFomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPWM2NmUxNDVhOTNmYTU2YTc3MDQ5ZDY0ZmRiZDU1NWJhMzBhNzkwZjUxNTEyZTAwYTVjYjEwYjNlNWM5MjYzNWUmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JmFjdG9yX2lkPTAma2V5X2lkPTAmcmVwb19pZD0wIn0.t5o8LjAlSX8IgvKbHrPEUn192nhtqkmEjl49q7TbNFs)
![image](https://private-user-images.githubusercontent.com/26236775/277551677-f0689d3f-8cb8-4a4b-9f34-3a909b4f5310.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MjEzMDAyNjQsIm5iZiI6MTcyMTI5OTk2NCwicGF0aCI6Ii8yNjIzNjc3NS8yNzc1NTE2NzctZjA2ODlkM2YtOGNiOC00YTRiLTlmMzQtM2E5MDliNGY1MzEwLnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNDA3MTglMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjQwNzE4VDEwNTI0NFomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTVlMjg0YWNkMTU1OWIyYWRlNThmYTY0MzZjYjI3OTM3ZDdiODhkNzAyNTY2OThhN2Q4ZjIzYzgwZGViMzRiZGUmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JmFjdG9yX2lkPTAma2V5X2lkPTAmcmVwb19pZD0wIn0.zXIJGBttobsatbVp0UVPmQ3rphRGBpieZ64Q2trB4zg)
考虑下把前后端个封进一个docker吗,这样直接compose up后端和数据redis啥的可以用compose的内联network也方便一点