我最近一直在研究领域驱动设计,必须说这种类型的架构设计触发了我的一些东西。当我尝试将它的概念应用到我的 Go 项目时,我遇到了一些障碍。以下是一些示例方法,但我不确定要使用哪种方法。
项目结构摘录:
├── api/
├── cmd/
├── internal/
| ├── base/
| | ├── eid.go
| | ├── entity.go
| | └── value_object.go
| ├── modules/
| | ├── realm/
| | | ├── api/
| | | ├── domain/
| | | | ├── realm/
| | | | | ├── service/
| | | | | ├── friendly_name.go
| | | | | ├── realm.go
| | | | | └── realm_test.go
| | | | └── other_subdomain/
| | | └── repository/
| | | ├── inmem/
| | | └── postgres/
所有方法通用:
package realm // import "git.int.xxxx.no/go/xxxx/internal/modules/realm/domain/realm"
// base contains common elements used by all modules
import "git.int.xxxx.no/go/xxxx/internal/base"
方法#1:
type Realm struct {
base.Entity
FriendlyName FriendlyName
}
type CreateRealmParams struct {
FriendlyName string
}
func CreateRealm(id base.EID, params *CreateRealmParams) (*Realm, error) {
var err error
var r = new(Realm)
r.Entity = base.NewEntity(id)
r.FriendlyName, err = NewFriendlyName(params.FriendlyName)
return r, err
}
type FriendlyName struct {
value string
}
var ErrInvalidFriendlyName = errors.New("invalid friendly name")
func (n FriendlyName) String() string { return n.value }
func NewFriendlyName(input string) (FriendlyName, error) {
if input == "" {
return ErrInvalidFriendlyName
}
// perhaps some regexp rule here...
return FriendlyName{value: input}, nil
}
使用这种方法,我认为从长远来看会有很多重复的代码,但至少 FriendlyName 值对象根据 DDD 要求是不可变的,并且可以附加更多方法。
这里的友好名称类型只是一个字符串,但不可变。这个结构让我想起了 Java 代码……在查找领域时,存储库层是否应该使用域模型中的设置方法来构造领域聚合?我尝试将 DTO 实现放置在同一个包 (dto_sql.go) 中,该包对领域聚合进行编码/解码,但是将这个问题放在域包中感觉有点不对劲。
如果您面临与我相同的问题,知道任何其他方法或有任何需要指出的,我将非常有兴趣收到您的来信!
aluckdog
相关分类