在GO中构建DDD Web应用程序

时间:2017-02-28 14:06:26

标签: go architecture domain-driven-design

我正在构建一个go web服务并试图遵循"清洁代码"或"域驱动设计"原则。我的精简文件夹结构如下所示:

- api
    - postgre
        employee_service.go
    employee.go

基本布局是我的root(api)文件夹是我的所有域代码。并且所有软件包都是适配器,以使我的域工作,但如果需要,很容易更换。我的employee.go文件可能如下所示:

type EmployeeService interface{
    CreateEmployee(e *Employee) error
}

type Employee struct {
    ID string
    Name string
}

我遇到的问题是在我的应用上放置某些东西,因为他们觉得他们是我的域逻辑的一部分;但是域逻辑不应该有任何外部依赖,所以它让我陷入困境。以下是我要创建新员工的示例:

postgre/employee_service.go:

type EmployeeService struct {
    DB *pg.DB
}

func (s *EmployeeService) CreateEmployee(e *api.Employee) error {
    e.ID = uuid.NewV4().String()

    // insert to db
}

现在你可以想象Employee结构域有更多的字段,而不仅仅是我需要在将它插入数据库之前设置的ID或名称。所以我的想法是在我的应用程序的根目录中为User结构添加一个方法,如下所示:

/employee.go    

func (e *Employee) New() {
    e.ID = uuid.NewV4()
    // add any other fields I need
}

postgre用户服务看起来像这样:

postgre/employee_service.go:

func (s *EmployeeService) CreateEmployee(e *api.Employee) error {
    e.New()

    // insert to db
}

现在问题是我的应用的域依赖于uuid包。在我看来这很好,因为如果我要更换postgre的mysql或mongo或任何其他DB New()方法不会改变。另外一个"复杂"例如密码哈希,无论数据库是什么,我的密码哈希都将生成相同,所以我相信这属于我的域逻辑所在的根文件夹。再次哈希密码我会crypto/bcrypt依赖性破坏DDD规则,你的域应该没有外部依赖。

0 个答案:

没有答案