Golang中这是什么架构?
Golang中这是什么架构? 你好,我一直使用这种架构,但不知道它是否有名称,或者这样使用是否合适。

4 回复
是的,每家公司都有自己的指南,类似这样的,比如 Uber 的指南。
更多关于Golang中这是什么架构?的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
golang-standards/project-layout 实际上是一个广为人知且具有误导性的例子,它根本不是一个“标准”项目布局的范例。请参阅 rsc 创建的此问题。说它“不是官方标准”并不完全准确,更准确的说法是 Go 团队积极不鼓励使用它。话虽如此,如果你有一个适合你和你的团队的项目布局,那就使用它。
我唯一尝试遵循的原则是:
- 尽可能保持简单,直到需要复杂化为止。我通常从根目录下只有一个
main.go文件开始,然后随着项目不可避免地增长而重新评估。 - 仔细考虑包的职责分离可以解决大多数难以处理的代码问题。
- 如果我有一个包含多个可执行文件的单体应用,我会坚持让每个可执行文件都位于
/cmd文件夹的子文件夹中。这似乎是一个相当标准的做法(至少在我所处的圈子里是这样;你的情况可能有所不同!)。
总之,原帖作者,你的文件夹结构看起来不错。特别是如果它对你有用的话。当我浏览它时,我可以很好地了解每个包的作用。唯一让我不是 100% 确定的是 tmp 文件夹,因为它可能代表多种含义。但我相信只要快速查看一下,就能解答我关于它的任何疑问。
这是典型的依赖注入(Dependency Injection)架构,结合了接口隔离和控制反转原则。这种架构在Go社区中广泛使用,特别是通过构造函数注入依赖。
架构分析
// 1. 定义接口(抽象层)
type UserService interface {
GetUser(id int) (*User, error)
CreateUser(user *User) error
}
type UserRepository interface {
FindByID(id int) (*User, error)
Save(user *User) error
}
// 2. 实现具体类型(实现层)
type userServiceImpl struct {
repo UserRepository
db *sql.DB
cfg *Config
}
// 3. 构造函数注入依赖
func NewUserService(repo UserRepository, db *sql.DB, cfg *Config) UserService {
return &userServiceImpl{
repo: repo,
db: db,
cfg: cfg,
}
}
// 4. 实现接口方法
func (s *userServiceImpl) GetUser(id int) (*User, error) {
// 使用注入的依赖
return s.repo.FindByID(id)
}
// 5. 在main函数或初始化层组装依赖
func main() {
db := initDatabase()
cfg := loadConfig()
repo := NewUserRepository(db)
userService := NewUserService(repo, db, cfg)
// 使用userService
}
关键特点
- 依赖注入:通过构造函数显式传入依赖
- 接口编程:依赖接口而非具体实现
- 单一职责:每个结构体只负责一个领域
- 可测试性:可以轻松mock依赖进行单元测试
测试示例
// 单元测试时可以mock依赖
type mockRepository struct {
mock.Mock
}
func (m *mockRepository) FindByID(id int) (*User, error) {
args := m.Called(id)
return args.Get(0).(*User), args.Error(1)
}
func TestUserService_GetUser(t *testing.T) {
mockRepo := new(mockRepository)
expectedUser := &User{ID: 1, Name: "John"}
mockRepo.On("FindByID", 1).Return(expectedUser, nil)
service := NewUserService(mockRepo, nil, nil)
user, err := service.GetUser(1)
assert.NoError(t, err)
assert.Equal(t, expectedUser, user)
mockRepo.AssertExpectations(t)
}
这种架构在Go项目中非常常见,特别适合中大型项目,能够有效降低耦合度,提高代码的可测试性和可维护性。


