清晰架构(Clean Architecture)的Go微服务: 程序设计

我使用Go和gRPC创建了一个微服务,并将程序设计和编程的最佳实践应用于该项目。 我写了一系列关于在项目工作中做出的设计决策和取舍的文章,此篇是关于程序设计。

程序的设计遵循清晰架构(Clean Architecture)¹。 业务逻辑代码分三层:用例(usecase),域模型(model)和数据服务(dataservice)。

有三个顶级包“usecase”,“model”和“dataservice”,每层一个。 在每个顶级包(模型除外)中只有一个以该包命名的文件。 该文件为每个包定义了外部世界的接口。 从顶层向下的依赖结构层次是:“usecase”,“dataservice”和“model”。 上层包依赖于较低层的包,依赖关系永远不会反向。

用例(usecase):

“usecase”是应用程序的入口点,本项目大部分业务逻辑都在用例层。 我从这篇文章²中获得了部分业务逻辑思路。 有三个用例“registration”,“listUser”和“listCourse”。 每个用例都实现了一个业务功能。 用例可能与真实世界的用例不同,它们的创建是为了说明设计理念。 以下是注册用例的接口:


// RegistrationUseCaseInterface is for users to register themselves to an application. It has registration related functions.
// ModifyAndUnregisterWithTx() is the one supporting transaction, the other are not.
type RegistrationUseCaseInterface interface {
   
	// RegisterUser register a user to an application, basically save it to a database. The returned resultUser that has
	// a Id ( auto generated by database) after persisted
	RegisterUser(user *model.User) (resultUser *model.User, err error)
	// UnregisterUser unregister a user from an application by user name, basically removing it from a database.
	UnregisterUser(username string) error
	// ModifyUser change user information based on the User.Id passed in.
	ModifyUser(user *model.User) error
	// ModifyAndUnregister change user information and then unregister the user based on the User.Id passed in.
	// It is created to illustrate transaction, no real use.
	ModifyAndUnregister(user *model.User) error
	// ModifyAndUnregisterWithTx change user information and then unregister the user based on the User.Id passed in.
	// It supports transaction
	// It is created to illustrate transaction, no real use.
	ModifyAndUnregisterWithTx(user *model.User) error
	// EnableTx enable transaction support on use case. Need to be included for each use case needs transaction
	// It replaces the underline database handler to sql.Tx for each data service that used by this use case
	EnableTxer
}

“main”函数将通过此接口调用“用例”,该接口仅依赖于模型层。

以下是“registration.go”的部分代码,它实现了“RegistrationUseCaseInterface”中的功能。 “RegistrationUseCase”是具体的结构。 它有两个成员“UserDataInterface”和“TxDataInterface”。 “UserDataInterface”可用于调用数据服务层中的方法(例如“UserDataInterface.Insert(user)”)。 “TxDataInterface”用于实现事务。 它们的具体类型由应用程序容器(ApplicationContainer)创建,并通过依赖注入到每个函数中。 任何用例代码仅依赖于数据服务接口,并不依赖于数据库相关代码(例如,sql.DB或sql.Stmt)。 任何数据库访问代码都通过数据服务接口执行。

// RegistrationUseCase implements RegistrationUseCaseInterface.
// It has UserDataInterface, which can be used to access persistence layer
// TxDataInterface is needed to support transaction
type RegistrationUseCase struct {
   
	UserDataInterface dataservice.UserDataInterface
	TxDataInterface   dataservice.TxDataInterface
}

func (ruc *RegistrationUseCase) RegisterUser(user *model.User) (*model.User, error) {
   
	err := user.Validate()
	if err != nil {
   
		return nil, errors.Wrap(err, "user validation failed")
	}
	isDup, err 
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值