古老的榕树

用 Go 开发终端接口服务--项目整体结构介绍

发表 2019-05-14 16:06 阅读(596)
通常一个项目我们建议分 dao service controller 三层 ,这样可以重用一些关键的部件,模块尽量趋于松耦合,分工明确便于维护。数据的传输方式,我们采用 JSON 格式数据发起 POST 请求,再返回 JSON 格式数据给终端,这样终端和服务端的数据格式都统一了,便于协调沟通,还可以提高数据传输过程中的安全性。但凡事不能绝对,主要还是统一规范,约定优于配置。

上一章节我们快速编写一个 Web 服务器的时候,新建了项目 chapter01 根目录,现在在根目录下,继续新建 src、template、static 三个文件夹,新建一个 config.ini 文件,然后再在 src 文件夹里新建 controller、service、dao、model、dbutil、common、util 几个文件夹(每个文件夹名就是一个个包),最后在这几个文件夹里,分别创建 init.go 文件,分别文件顶部指定各自的包名,如  controller 里的 init.go 文件,首行指定了 package controller,其他包同样的步骤操作。整个项目大致结构就构建好了。

项目 chapter01 整体的结构:

chapter01   
│  config.ini                                
│  Gopkg.lock                                
│  Gopkg.toml                                
│  server.go                                 
├─media                                      
│  └─images                                  
├─src                                        
│  ├─common                                  
│  │      config_util.go                     
│  │      constant.go                        
│  │      init.go                            
│  │      service_util.go                    
│  │      upload_util.go                     
│  ├─controller                              
│  │      init.go                            
│  │      product.go                         
│  │      run_testcase.go                    
│  ├─dao                                     
│  │      init.go                            
│  │      product.go                         
│  │      product_photo.go                   
│  ├─dbutil                                  
│  │      sqlx_util.go                       
│  ├─model                                   
│  │      init.go                            
│  │      product.go                         
│  │      product_photo.go                   
│  ├─service                                 
│  │      init.go                            
│  │      product.go                         
│  │      product_photo.go                   
│  ├─test                                    
│  │      data.go                            
│  │      model.go                           
│  │      util.go                            
│  └─util                                    
│          file_util.go                      
│          http_util.go                      
│          image_util.go                     
│          init.go                           
│          pager_util.go                     
│          request_util.go                   
│          response_util.go                  
├─static                                     
│  ├─css                                     
│  ├─images                                  
│  └─js                                      
├─template                                   
│      run_api_test_index.html               
│      run_api_test_result.html              
└─vendor    

项目名为 chapter01 ,里面有 src、template、static 三个文件夹,src 里面存放 Go 的业务源代码,template 是 html、tmpl 模板文件,主要是渲染视图用的,static 是静态文件夹,存放一些 css、js、images 文件。其中 go build 编译的时候,templates 和 static 文件是不会编译的,这些文件和路径都原样保留,当前项目主要是提供服务类型的项目,可能有些文件夹暂时用不上,但为了项目的完整性讲解,所以有些典型的文件夹都会保留。

另外 chapter01 根目录下,还有 service.go、config.ini 两个关键文件, service.go 是程序的启动入口,上一章说过里面是一个 Web 服务器,config.ini 是项目配置文件,项目主要的配置参数都写在里面,项目启动时会把配置项一次性读取到内存里,项目按需使用即可。

着重说说 src 里面的子文件夹,src 有四个重要的 package 包 controller、service、dao、model 都是手动新建的文件夹,在里面新建业务 go 文件,每个文件夹相当于 package 包的概念。四个文件包就是我们项目常见的控制器层、业务服务层、数据操作层、实体结构层,这四个层,一般是从左到右调用的,这是他们的关系,比如 控制器层一般都是调用服务层的函数,而业务服务层调用数据操作层的函数,数据层调用实体层的结构体,一般不建议跨级调用,比如不建议 控制器越过服务层直接调用数据层操作层的函数,这样很混乱,不符合规范。不过 model 层的结构体属于底层的部分,可以同时被以上多层调用,它对于其他层来说,是共用的底层结构体,不受以上限制。

vendor 文件夹是依赖管理工具 dep 自动生成的,它存放着所有 dep 安装的类包源文件,根目录下的 Gopkg.lock 和  Gopkg.toml 是 dep 的专属配置文件,一般 Gopkg.lock 不需要开发者理会,请不要手动修改,而 Gopkg.toml 是核心的配置文件,开发者可以在里面定义哪些是必需包,哪些是可忽略包,定义包的版本号和路径等信息。

src 源文件里,除了重要的四个包,还有另外的 dbutil、util、common 三个包, dbutil 是专门实例化数据库 DB 对象的工具包。util 和 common 都是公共工具包,区别是 util 是和项目业务关联性不太紧密的工具包,可以在多个项目中共用的,不依赖项目的任何东西,一般里面的函数功能只使用 Go 内置的底层类包实现,而 common 和项目关联是非常密切的,甚至和项目的其他包存在依赖关系,如果把它移植到其他项目上,不一定行得通,它仅适合在自身项目上作用,它就是某个项目集合工具包,不是属于所有项目的,比如 common 包某个函数需要依赖 model 结构体,依赖 service 的函数,依赖 util 的函数,依赖外部配置属性等。所以从某种意义上来说 util 才是所有项目的工具包,依赖某个具体项目业务的函数,是不适合放在 util 包里的。

项目涉及 Product 产品、Product Photo 产品图片这两个业务模块,它们都很具有代表性,本系列教程把它们作为讲解对象,把典型的技术问题完整描述清楚。

小结
项目的包和文件的命名很讲究,整体上来看,每个层就是一个包,包里可以有若干个 go 文件,我们根据业务模块新建不同的文件。Go 语言的命名遵循驼峰式命名,但一般是指 go 文件里的代码命名,比如定义常量、变量和函数命名等,强烈建议采用标准的驼峰式命名,首字母大写的对象,表示对外公开,可跨包访问(它是公有对象),首字母小写的只限于自己所在包使用(它是私有对象);但在 Go 语言里,包名和文件名却是使用非驼峰式命名,而且都尽量使用单个词命名,比如 service 包,如果无法做到单个词,可通过下划线隔开,比如 product_photo.go 文件,也可不用下划线,比如 dbutil 包,就是由 db 和 util 两个词组成的,Go 语言开发团队对 package 包的命名,都喜欢小写的单个词命名,其次多个小写的词直接组合,不得已的时候才用下划线(很少见用下划线的包名);而包里的文件,也是一样的规则,不过下划线命名稍常见一些,项目更多规范,读者可以参照上章节的 Go 语言编码规范。



《用 Go 开发终端接口服务》 目录


Donate

如果文章对您有帮助,请使用手机支付宝扫描二维码,捐赠X元,作者离不开读者的支持!