最近在对之前的代码做重构,从之前的 MVC 结构切换到 Clean Arch 的结构,但是在切换的时分关于代码作风出现了一些困惑。
在下面的代码中 repository 是存储库,主要用于封装数据库查询或许是第三方微效劳的调用,它完成了 domain.IAzRepository 接口,其他层的代码都只依赖这个接口而不依赖详细的完成
三种代码作风
作风一
在 Go 中我们常常“前往完成(struct),依赖接口”,其实就是在函数前往的时分我们前往一个详细的完成,函数的参数或许是 Struct 的成员部分我们依赖接口,这个作风看起来是违犯了这个准绳的
// repository 存储库
type repository struct {
db *gorm.DB
}
// NewAZRepository NewAZRepository
func NewAZRepository(db *gorm.DB) domain.IAzRepository {
return &repository{db: db}
}
作风二
这个作风前往了完成,并且由于并没有导出看起来也具有封装的特性,但是假设你运转 golint 你就会发现会抛出错误,由于这么写,会招致我们用导出的办法将没有导出 struct 给暴露了出去
// repository 存储库
type repository struct {
db *gorm.DB
}
// NewAZRepository NewAZRepository
func NewAZRepository(db *gorm.DB) *repository {
return &repository{db: db}
}
作风三
这个写法的主要成绩是,由于 Repository 被导出,所以在外部其他的包中就可以直接经过 &Repository{} 停止初始化,这样初始化之后运用就会招致 panic,由于成员函数是一个 nil 指针
// Repository 存储库
type Repository struct {
db *gorm.DB
}
// NewAZRepository NewAZRepository
func NewAZRepository(db *gorm.DB) *Repository {
return &Repository{db: db}
}
选择
选择总是困难的,带着这个成绩我咨询了同组的同事还有好几个 Go 言语交流群的同窗,其中大部分都会选择作风三,小部分会选择作风一,作风二简直没有人选择。最后我选什么呢?
最后我的选择是作风一,这是针对场景来的,由于我们的这个包其实不希望其他包直接依赖完成,由于后续有能够随着开展被独自拆分红一个微效劳或许是需求改换存储库,假设外部有包直接依赖 repository 会招致后续的重构比较困难
除此之外,我们在其他中央普通还是会选择作风三,由于结构体名不导出,外部其实没有比较好的办法停止初始化,例如想要 var r Repository ,至于前面提到的直接字面量初始化的成绩,我们可以经过一致代码作风处置。
在 外部包 中除了用于参数传递的 Option 结构之外,其他的不允许直接经过 &XXX{} 的方式停止初始化
【编辑引荐】
压力山大!运营商靠5G盈利,能够比想象的更难
Go言语基础之结构体(春日篇)
工信部:4G用户达12.96亿户 占比为80.9%
代码不止 | 2020 Google 开发者大会亮点回忆
Golang GinWeb框架-快速入门/参数解析
(责任编辑:admin)