该功能特性从v2.1版本开始提供。

基本介绍

设计背景

在业务项目实践中,业务逻辑封装往往是最复杂的部分,同时,业务模块之间的依赖十分复杂、边界模糊,无法采用Golang包管理的形式。如何有效管理项目中的业务逻辑封装部分,对于每个采用Golang开发的项目都是必定会遇到的难题。

设计目标

  1. 增加logic分类目录,将所有业务逻辑代码迁移到logic分类目录下,采用包管理形式来管理业务模块。
  2. 业务模块之间的依赖通过接口化解耦,将原有的service分类调整为接口目录。这样每个业务模块将会各自维护、更加灵活。
  3. 可以按照一定的项目规范,从logic业务逻辑代码生成service接口定义代码。同时,也允许人工维护这部分service接口。

命令使用

该命令通过分析给定的logic业务逻辑模块目录下的代码,自动生成service目录接口代码。

需要注意:

  1. 由于该命令是根据业务模块生成service接口,因此只会解析二级目录下的go代码文件,并不会无限递归分析代码文件。以logic目录为例,该命令只会解析logic/xxx/*.go文件。因此,需要logic层代码结构满足一定规范。
  2. 不同业务模块中定义的结构体名称在生成的service接口名称时可能会重复覆盖,因此需要在设计业务模块时保证名称不能冲突。

手动模式

如果是手动执行命令行,直接在项目根目录下执行 gf gen service 即可。

$ gf gen service -h
USAGE
    gf gen service [OPTION]

OPTION
    -s, --srcFolder         source folder path to be parsed. default: internal/logic
    -d, --dstFolder         destination folder path storing automatically generated go files. default: internal/service
    -f, --dstFileNameCase   destination file name storing automatically generated go files, cases are as follows:
                            | Case            | Example            |
                            |---------------- |--------------------|
                            | Lower           | anykindofstring    |
                            | Camel           | AnyKindOfString    |
                            | CamelLower      | anyKindOfString    |
                            | Snake           | any_kind_of_string | default
                            | SnakeScreaming  | ANY_KIND_OF_STRING |
                            | SnakeFirstUpper | rgb_code_md5       |
                            | Kebab           | any-kind-of-string |
                            | KebabScreaming  | ANY-KIND-OF-STRING |
    -w, --watchFile         used in file watcher, it re-generates all service go files only if given file is under
                            srcFolder
    -a, --stPattern         regular expression matching struct name for generating service. default: ^s([A-Z]\\w+)$
    -p, --packages          produce go files only for given source packages
    -i, --importPrefix      custom import prefix to calculate import path for generated importing go file of logic
    -l, --clear             delete all generated go files that are not used any further
    -h, --help              more information about this command

EXAMPLE
    gf gen service
    gf gen service -f Snake

参数说明:

名称必须默认值含义
srcFolderinternal/logic指向logic代码目录地址
dstFolderinternal/service指向生成的接口文件存放目录
dstFileNameCaseSnake生成的文件名名称格式
stPatterns([A-A]\w+)

使用正则指定业务模块结构体定义格式,便于解析业务接口定义名称。在默认的正则下,所有小写s开头,大写字母随后的结构体都将被当做业务模块接口名称。例如:

logic结构体名称service接口名称
sUserUser
sMetaDataMetaData
watchFile

用在代码文件监听中,代表当前改变的代码文件路径

packages

仅生成指定包名的接口文件,给定字符串数组,通过命令行传参则给定JSON字符串,命令行组件自动转换数据类型
importPrefix

指定生成业务引用文件中的引用包名前缀
overwrite
true生成代码文件时是否覆盖已有文件
clear
false自动删除logic中不存在的接口文件(仅删除自动维护的文件)

自动模式

如果您是使用的GolandIDE,那么可以使用我们提供的配置文件:watchers.xml  自动监听代码文件修改时自动生成接口文件。使用方式,如下图:

具体使用手摸手

Step1:引入我们提供的配置

我们建议您在使用Goland IDE时,使用我们提供的配置文件:watchers.xml 

Step2:编写您的业务逻辑代码

Step3:生成接口及服务注册文件

如果您已经按照Step1做好了配置,那么这一步可以忽略。因为在您编写代码的时候,service便同时生成了接口定义文件。

否则,每一次在您开发/更新完成logic业务模块后,您需要手动执行一下 gf gen service 命令。

Step4:注意服务的实现注入部分(仅一次)

只有在生成完成接口文件后,您才能在每个业务模块中加上接口的具体实现注入。该方法每个业务模块加一次即可。

Step5:在启动文件中引用接口实现注册(仅一次)

可以发现,该命令除了生成接口文件之外,还生成了一个接口实现注册文件。该文件用于在程序启动时,将接口的具体实现在启动时执行注册。

该文件的引入需要在main包的最顶部引入,需要注意import的顺序,放到最顶部,后面加一个空行。如果同时存在packed包的引入,那么放到packed包后面。像这样:

Step6:Start&Enjoy

启动main.go即可。

常见问题FAQ

快速定位接口的具体实现

项目业务模块采用接口化解耦后体验非常棒!但是我在开发和调试过程中,想要快速找到指定接口的具体实现有点困难,能给点指导思路吗?

> 这里我推荐使用Goland IDE,有个很棒的接口实现定位功能,具体如图。找到接口定义后,点击左边的小图标可快速定位具体的实现。如果Goland不显示小图标,可以尝试升级使用最新版本的Goland哈。






Content Menu

  • No labels

19 Comments

  1. // ==========================================================================
    // Code generated by GoFrame CLI tool. DO NOT EDIT.
    // ==========================================================================

    package service

    import (
    "context"
    "pms/internal/consts"
    "pms/internal/dao"
    "pms/internal/model"
    "pms/internal/model/do"
    "pms/internal/model/entity"
    "pms/utility"

    "github.com/gogf/gf/v2/frame/g"
    "github.com/gogf/gf/v2/os/grpool"
    )

    生成的service 文件的import 部分不正确是什么原因呢?
    1. GF Version:  v2.1.2 已经解决.

  2. 生成service的文件名全是小写,是不是应该与service保持一致.

    1. 针对这个问题有给强哥提了PR,希望能被合并~
      https://github.com/gogf/gf/pull/1953

      1. 我看了代码,好像是刻意转成小写的呢.另外请教您一下.我测试时生成的service会一些用不到的包,这个您了解是什么问题吗?

        1. 强哥说是bug,目前可以通过 goimports 工具自动清理多出包。

    2. GF Version:  v2.1.2 已经解决.

  3. 生成service时,没有判断逻辑代码是否注释.即使注释的方法也会生成;

  4.  这里我推荐使用GolandIDE,有个很棒的接口实现定位功能,具体如图。找到接口定义后,点击左边的小图标可快速定位具体的实现。

    Code generated by GoFrame CLI tool. DO NOT EDIT.

    老大,这个要把生成的头部修改一下,小图标才能出现.有上边这个就没有小图标.

  5. 自定义目录,会提示:

    source folder path "internal/logic" does not exist

  6. 郭强 强仔  郭老板 您的GolandIDE 什么版本的,我这没有你说的那个小图标呀?

  7. 强仔  把文件的

    Code generated by GoFrame CLI tool. DO NOT EDIT.  删除了就有小图标了!
  8. 请问我用gf gen service 为什么生成不了service文件,都需要哪些步骤 

    logic 文件已经写好了

    ll internal/logic/
    drwxr-xr-x  3 root root 4096 Sep 16 17:18 ./
    drwxr-xr-x 11 root root 4096 Sep 14 15:51 ../
    drwxr-xr-x  2 root root 4096 Sep 16 17:18 camera_type/


    gf gen service
    done!

    只是返回了done 然后就没了

    servcice还是空的


  9. 你的那个是手动执行,自动不香么。。。
    但我的也是,怀疑是作者偷懒。你需要自己先写一下注入和接口名称,将接口和实现函数关联(就是类似java中的构造方法,我总是搞混,魔怔了),然后你改动logic中实现方法,就会自动自动创建service中接口,不需要每次都改。

    1. 谢谢回复,不用自动是因为电脑用goland占用内存太大,然后我这这边排查了下,发现问题有个logic的返回值少了一个空格,这可太难受了

  10. gcf

    请问如何将logic进行分组生产不同分组service?

    当前gf gen logic仅可以对logic下面的儿子目录生产service,因为项目稍微大了之后,logic就需要进分组了,需要将某些逻辑分组生产不同的service进行保存。研究了半天没研究出来该怎么做。求破!

  11. 有没有针对 vscode 的插件哦

  12. 我在logic层的方法返回了一个errors.New("xxxx")这种的,会导致生成的service中多一行

    import errors

    但是这个引用在service文件中没有使用,打包的时候就会一直提示,当然可以手动删掉,但是每次生成又会从新出现

  13. 如果在logic上继承了某个结构体,例如gf-jwt

    type sAuth struct {
       *jwt.GfJWTMiddleware
    }

    生成出来的service并没有jwt.GfJWTMiddleware里面的方法,这样请问要如何解决?