一、时间安排
2022-04-28 21:00 如遇不可预料的时间冲突,时间另行交流确定。
预计会议时间 30 分钟。
二、会议地址
郭强 邀请您参加腾讯会议
会议主题:GoFrame工程化改进交流:接口化、依赖注入设计
会议时间:2022/04/28 21:00-21:30 (GMT+08:00) 中国标准时间 - 北京
点击链接入会,或添加至会议列表:
https://meeting.tencent.com/dm/VwOiDwqfApbG
#腾讯会议:712-775-838
复制该信息,打开手机腾讯会议即可参与
三、会议内容
本次会议由 郭强 提供主题和一些思考、验证功能分享,对其中的内容大家可以结合现有的行业实现提供合理的建议,共同讨论。
1、工程化中的一些痛点
- 在工程目录设计中,service层沉淀的业务逻辑越来越多,后期的维护越来越复杂
- service层单目录下过多的代码文件,小心翼翼组织代码,造成压抑的代码开发体验
- service无法使用包管理,否则极易出现循环包依赖问题,因此必须采用接口化解耦
2、基础分层仍旧按照职责分层
- 基础分类按照功能职责,极大规避业务包依赖
- 例如,controller层作为独立的controller包,可以依赖所有的service业务包,因此在一个请求中可以通过调用不同的业务包方法来实现功能,这也是鼓励的做法
- 对service层按照业务模块进行包管理。从包设计理论上来讲,一个包应当尽量低耦,这种低耦不仅是代码上的,更是逻辑上的。一个业务包中难以通过依赖过多的其他业务包来实现功能。
3、部分层级仍旧采用单包管理
- 例如
api/controller/consts/model
包 - 这部分层级从工程设计以及长期维护来讲,低复杂度,无需采用包管理
- 这部分层级的代码采用包管理的成本会高于单包维护成本,这是从务实考虑
4、提高效率的工具命令设计
gf gen service
- 自动根据logic层包代码分析生成service层接口、logic自动引用文件
- 支持Goland集成,支持编码中自动更新service
- 接口的实现需要开发者在业务包中手动注入
5、API接口层与gRPC支持的思考
- 使用api层管理业务的输入输出
- 不同协议的支持由工程自动生成的代码实现:不需要学习proto语法、也没有中间协议学习负担
- 对于其他微服务通信协议也同样如此
- 这样才能实现 开发者只需要关心业务 的目标,一个框架本该就如此
四、视频地址
https://www.bilibili.com/video/BV1m34y1e7MN/
13 Comments
海亮
部分留言:
郭强
stephen
service
跟logic
是接口与实现的关系,目前这样是分离的,建议放到同一个层级下。这样目录会更清晰。gf gen
目前是跟库表对应的,业务逻辑经常会多表组合来实现,难免service
会相互调用实现逻辑目标,如果都放controller
去调service
又会让controller
承载太多跟接口无关的业务逻辑。有什么好建议?dao
目录是否还是放service
下,保持好的调用规范与习惯呢?企业级团队对项目统一调用方向还挺重要的,降低沟通理解成本。郭强
1.
logic
是具体的业务逻辑封装、具体的业务实现。service
在后续都只会有接口定义、基本的接口注入和实现获取,目的是将logic
中各个业务模块按照接口进行解耦。两者的职责很明确、界限是很清晰的,因此我们刻意将logic
和service
分离。此外,如果业务模块过多,
service
在后续可能也会比较复杂,如果两者放同一层级的话会比较混乱。再者,挺大一部分的场景下,大家只会关心
logic
实现,并不会关心service
的存在,因为service
可以由工具完全接管维护,自动代码生成。2. 这是开发常见问题,我在昨晚会议中也提到过,在
controller
聚合多个业务模块结果,或者在logic
方法中聚合多个业务模块实现功能两种开发方式都存在。前者在controller
中耦合,后者在logic
业务模块中耦合。我个人推荐尽量在前者中聚合维护,让各个业务模块尽量低耦。前者的好处是,一旦logic
完善后,controller
就可以通过不同的logic
业务模块搭配来实现不同的api
。后者的缺陷是,会造成logic
的特定方法只为特定的api
服务,耦合较大、难以复用,很难实现前者的好处。同时,一旦与客户端约定的api
结构变动,也会影响内部logic
功能,这是不太合理的。不过,知易行难,参差不齐的开发者往往很难掌握其中的力道。写代码是门手艺,拿捏得道却是门艺术。3. 下个版本,生成的
dao/do
都可以自定义生成位置。stephen
关于第二点,认同。但是建议
gf gen service
不要强行跟表一一对应进行分包,因为很多内部逻辑是跨多表实现的,例如订单head
表与订单detail
表。都搬去controller
才能进行编写订单逻辑,显然会让controller
太重,而service
只剩下CURD
的功能。建议使用domain
业务领域的设计,同一业务领域的逻辑本就应该在同一个包里进行调用。郭强
哦,你这么说,我在这里有个重点忘了提醒了!
service
的接口设计和数据表没有任何关系,只跟logic
业务逻辑封装对象有关系,多个接口在service
下是单包管理方式,可能会存在重名情况(这块代码生成工具会报错提醒)。logic
下的包是开发者自己命名的,一般按照业务模块来封装,按照领域模型来设计也是可以的,自由发挥。佳雨
关于代码生成的顺序有个建议:
1,定义api文件
2,工具跟据api的定义生成service的接口
3,再去实现logic的俱体实现。
这样更符合习惯。
郭强
api/controller/model/logic/service
api
定义去生成controller
,但是service
是属于内部业务模块通用性的功能定义接口,不应该和外部api
耦合的捡馒头渣的小戴
请问一下有提供启用多个server的方法吗?没有得话,下面这种方式可行吗?
海亮
可以用server.Start()启动多个 ghttp package - github.com/gogf/gf/v2/net/ghttp - pkg.go.dev
server.Wait()阻塞
郭强
可以的,有两种方法,一种是多端口监听,参考示例:开始使用
另外一种是多个
Server
相同端口监听,通过SetListener
实现。Eric
您好,相同端口监听,使用SetListener如何实现,可以给个demo嘛
刘保强
像一些web接口,避免不了会有很多增删改查的操作,怎么去定义一些公共的方法去实现不同数据表的增删改查的调用。