首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Golang代码结构

Golang代码结构
EN

Stack Overflow用户
提问于 2017-02-19 00:28:57
回答 2查看 202关注 0票数 2

是否值得在结构中对方法进行分组:例如:

代码语言:javascript
复制
type UserManager struct {
    DB *sql.DB
}

func (m UserManager) Insert (u User) error {...}
func (m UserManager) Delete (u User) error {...}
...

或者它更简单,只支持单独的功能。

代码语言:javascript
复制
func InsertUser (u User, db *sql.DB) error {...}

虽然第二种方法一开始看起来更简单,但在未来这种方式下,包中可能会有很多函数。我应该为每个域聚合创建单独的包吗?到目前为止,我看到的示例中只有model包。我主要从事面向对象语言的工作,所以这里需要一些关于go最佳实践的建议。

EN

回答 2

Stack Overflow用户

发布于 2017-02-19 02:24:14

你的第二个建议不是好的go代码!为什么?因为在最好的情况下,函数应该将接口作为输入。

所以InsertUser函数应该看起来像这样,它会把你的第一个建议和第二个建议结合起来:

代码语言:javascript
复制
type Inserter interface {
   Insert(User)error
}
func InsertUser(i Inserter) error {...}

在这种情况下,测试您的函数很容易,因为您可以很容易地模拟插入器。

票数 1
EN

Stack Overflow用户

发布于 2017-02-19 02:34:22

或者都不是--在我看来,这真的无关紧要,因为惯用的方法是使用接口来组织这些概念:

代码语言:javascript
复制
package user

type User ...

type Inserter interface { Insert(User) error }
type Deleter interface { Delete(User) error }
type Manager interface { Inserter, Deleter } // bloated interface

本例中的User可能是一个具体的row类型,就像您的示例中一样,但也可以将其转换为不提及这些类型的接口。

如果您编写引用这些接口的函数,那么您可以使用embedding & promoted fields快速地粘合在一起。

在您的例子中,很明显,坚持第一种实现风格要简单得多:

代码语言:javascript
复制
type userManager struct { ... }
func (userManager) Insert(u User) error { ... }
func (userManager) Delete(u User) error { ... }

userManager是一个私有类型,所以只要它满足公共接口,就可以不受关注地进行更改。

保持接口与实现的解耦使得缩小接口范围变得更容易,因此,您可以找出您真正需要哪些接口来完成任务,而不是只有一个“用户管理器”或其他东西。顺便说一句,这种方法有一个很好的特性,它非常适合object capability model,这有助于简化诸如基于角色的访问控制之类的事情。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42317700

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档