go语言过渡到DDD(二)

332 阅读3分钟

这是我参与2022首次更文挑战的第20天,活动详情查看:2022首次更文挑战

本文为译文,原文链接:www.calhoun.io/moving-towa…

接上一篇,我们继续讲一下遇到编译报错的问题。

在这里你会有一些想法:

  1. 修改你的中间件来让UserService接口返回一个gitlab.User,而不是github.User
  2. 特意为GitLab创建一个新的鉴权中间件
  3. AuthMiddleware创建一个通用的用户类型来允许你的github和gitlab来实现互相切换。

答案: (1) 如果你足够自信你的公司会坚持gitlab,这点可能会行得通。当然,你将需要修改userservice和mocks,但是这个是一次性的修改,也不算太差。 换句话说,你并不知道你的组织会坚持使用gitlab。毕竟,谁能让哥斯拉的攻击,来决定他们的决定进程呢? 这种观点也可能存在问题,如果你的应用程序中的很多代码到处都是依赖了由这个包返回的github.User这个类型。 (2) 可以工作,但是看起来有点傻。为什么没有任何逻辑改变的时候,我们需要去重写所有的那些代码和那些单测呢?明确的是就像你一开始期望的那样,必须有一种方式来让这个接口可以工作。毕竟,那个中间件真的不关心user怎么查找的,它只需要一些关键的信息。 所以你决定试一试答案(3)。你将会在mw包中创建一个User类型,然后你将会适配器adapter来连接上你创建的GitLab客户端。

package mw

type User struct {
  OrgIDs []string
}

type UserService interface {
  User(token string) (User, error)
}

就在你写代码的时候,你有了另一种认识;因为你并不真正关心像用户user的ID或者email,你可以把那些字段从那你的mw.User类型中剔除出去。所有你需要指定的是你真正关心的字段,这样也会更简单和测试。太棒了!

下一步你需要创建一个适配器,所以你开始干了。

// Package adapter probably isn't a great package name, but this is a
// demo so deal with it.
package adapter

type GitHubUserService struct {
  Client *github.Client
}

func (us *GitHubUserService) User(token string) (mw.User, error) {
  ghUser, err := us.Client.User(token)
  if err != nil {
    return mw.User{}, err
  }
  return mw.User{
    OrgIDs: ghUser.OrgIDs,
  }, nil
}

type GitLabUserService struct {
  Client *gitlab.Client
}

func (us *GitLabUserservice) User(token string) (mw.User, error) {
  glUser, err := us.Client.User(token)
  if err != nil {
    return mw.User{}, err
  }
  return mw.User{
    OrgIDs: glUser.OrgIDs,
  }, nil
}

你也需要更新你的mock文件,但是这个改起来会很快。

package mock

type UserService struct {
  UserFn func(token string) (mw.User, error)
}

func (us *UserService) Authenticate(token string) (mw.User, error) {
  return us.UserFn(token)
}

现在你想使用我们的AuthMiddleware,无论是Github还是Gitlab,你都可以做到像这样:

var myHandler http.Handler
var us mw.UserService
us = &GitLabUserservice{
  Client: &gitlab.Client{
    Key: "abc-123",
  },
}
// This protects your handler
myHandler = mw.AuthMiddleware(us, "my-org-id", myHandler)

诶,我们终于有一个解决方案来完全解耦了。我们可以很简单地在github和gitlab之间切换了。当新的髋关节源控制公司启动时,我们准备跳上这一潮流。

你是否认为到这里就很完美了呢?且听下回分解。