Loading...
Loading...
Compare original and translation side by side
*TTNewX()internal/domain/context.Context*TTNewX()internal/domain/context.Contextinternal/
├── domain/ # Domain layer (no external deps)
│ ├── customer/ # One package per aggregate
│ │ ├── customer.go # Aggregate root entity
│ │ ├── repository.go # Repository interface
│ │ ├── email.go # Value objects
│ │ ├── events.go # Domain events
│ │ └── errors.go # Domain errors
│ ├── order/
│ │ ├── order.go
│ │ ├── repository.go
│ │ ├── item.go # Child entity
│ │ └── money.go # Value object
│ └── shared/ # Shared kernel
│ ├── events.go # Event interface
│ └── specification.go # Generic specification
│
├── application/ # Application services (orchestration)
│ ├── command/
│ │ └── place_order.go
│ └── query/
│ └── get_customer.go
│
└── infrastructure/ # Technical implementations
├── postgres/
│ ├── customer_repo.go
│ └── order_repo.go
└── eventbus/
└── in_memory.gointernal/
├── domain/ # 领域层(无外部依赖)
│ ├── customer/ # 每个聚合对应一个包
│ │ ├── customer.go # 聚合根实体
│ │ ├── repository.go # 仓库接口
│ │ ├── email.go # 值对象
│ │ ├── events.go # 领域事件
│ │ └── errors.go # 领域错误
│ ├── order/
│ │ ├── order.go
│ │ ├── repository.go
│ │ ├── item.go # 子实体
│ │ └── money.go # 值对象
│ └── shared/ # 共享内核
│ ├── events.go # 事件接口
│ └── specification.go # 通用规约
│
├── application/ # 应用服务层(编排逻辑)
│ ├── command/
│ │ └── place_order.go
│ └── query/
│ └── get_customer.go
│
└── infrastructure/ # 技术实现层
├── postgres/
│ ├── customer_repo.go
│ └── order_repo.go
└── eventbus/
└── in_memory.go| Pattern | Go Idiom | Receiver | Identity |
|---|---|---|---|
| Entity | Struct + pointer receiver | | By ID |
| Value Object | Type alias or struct + value receiver | | By value |
| Aggregate Root | Entity + unexported children | | By ID |
| Repository | Interface in domain package | N/A | N/A |
| Domain Service | Stateless struct with deps | | N/A |
| Domain Event | Immutable struct | | By name+time |
| Factory | | N/A | N/A |
| Specification | Generic interface | | N/A |
| 模式 | Go惯用写法 | 接收器类型 | 标识方式 |
|---|---|---|---|
| 实体 | 结构体 + 指针接收器 | | 通过ID |
| 值对象 | 类型别名或结构体 + 值接收器 | | 通过值内容 |
| 聚合根 | 实体 + 未导出子对象 | | 通过ID |
| 仓库 | 接口定义在领域包中 | N/A | N/A |
| 领域服务 | 无状态结构体(包含依赖) | | N/A |
| 领域事件 | 不可变结构体 | | 通过名称+时间 |
| 工厂 | | N/A | N/A |
| 规约 | 泛型接口 | | N/A |
EmailMoneyAddressinfrastructure/EmailMoneyAddressinfrastructure/references/entities-and-value-objects.mdreferences/aggregates-and-repositories.mdreferences/events-and-specifications.mdreferences/anti-patterns.mdreferences/entities-and-value-objects.mdreferences/aggregates-and-repositories.mdreferences/events-and-specifications.mdreferences/anti-patterns.mdtype Order struct {
id uuid.UUID
status Status
items []Item
createdAt time.Time
}
func NewOrder(customerID uuid.UUID) (*Order, error) {
return &Order{
id: uuid.New(),
status: StatusDraft,
items: make([]Item, 0),
createdAt: time.Now(),
}, nil
}
func (o *Order) AddItem(product ProductID, qty int, price Money) error {
if o.status != StatusDraft {
return ErrOrderNotDraft
}
o.items = append(o.items, NewItem(product, qty, price))
return nil
}type Order struct {
id uuid.UUID
status Status
items []Item
createdAt time.Time
}
func NewOrder(customerID uuid.UUID) (*Order, error) {
return &Order{
id: uuid.New(),
status: StatusDraft,
items: make([]Item, 0),
createdAt: time.Now(),
}, nil
}
func (o *Order) AddItem(product ProductID, qty int, price Money) error {
if o.status != StatusDraft {
return ErrOrderNotDraft
}
o.items = append(o.items, NewItem(product, qty, price))
return nil
}type Money struct {
amount int64
currency string
}
func NewMoney(amount int64, currency string) (Money, error) {
if currency == "" {
return Money{}, ErrInvalidCurrency
}
return Money{amount: amount, currency: currency}, nil
}
func (m Money) Add(other Money) (Money, error) {
if m.currency != other.currency {
return Money{}, ErrCurrencyMismatch
}
return Money{amount: m.amount + other.amount, currency: m.currency}, nil
}type Money struct {
amount int64
currency string
}
func NewMoney(amount int64, currency string) (Money, error) {
if currency == "" {
return Money{}, ErrInvalidCurrency
}
return Money{amount: amount, currency: currency}, nil
}
func (m Money) Add(other Money) (Money, error) {
if m.currency != other.currency {
return Money{}, ErrCurrencyMismatch
}
return Money{amount: m.amount + other.amount, currency: m.currency}, nil
}func (o *Order) Place() error {
if len(o.items) == 0 {
return ErrEmptyOrder
}
if o.status != StatusDraft {
return ErrOrderNotDraft
}
o.status = StatusPlaced
o.events = append(o.events, NewOrderPlacedEvent(o.id, o.Total()))
return nil
}func (o *Order) Place() error {
if len(o.items) == 0 {
return ErrEmptyOrder
}
if o.status != StatusDraft {
return ErrOrderNotDraft
}
o.status = StatusPlaced
o.events = append(o.events, NewOrderPlacedEvent(o.id, o.Total()))
return nil
}// domain/order/repository.go
type Repository interface {
Find(ctx context.Context, id uuid.UUID) (*Order, error)
Save(ctx context.Context, order *Order) error
Update(ctx context.Context, id uuid.UUID, fn func(*Order) error) error
}// domain/order/repository.go
type Repository interface {
Find(ctx context.Context, id uuid.UUID) (*Order, error)
Save(ctx context.Context, order *Order) error
Update(ctx context.Context, id uuid.UUID, fn func(*Order) error) error
}type OrderPlaced struct {
orderID uuid.UUID
total Money
occurredAt time.Time
}
func (o *Order) PullEvents() []Event {
events := o.events
o.events = nil
return events
}type OrderPlaced struct {
orderID uuid.UUID
total Money
occurredAt time.Time
}
func (o *Order) PullEvents() []Event {
events := o.events
o.events = nil
return events
}type TransferService struct {
accountRepo account.Repository
}
func (s *TransferService) Transfer(ctx context.Context, from, to uuid.UUID, amount Money) error {
// Load aggregates, validate domain rules, coordinate changes
}type TransferService struct {
accountRepo account.Repository
}
func (s *TransferService) Transfer(ctx context.Context, from, to uuid.UUID, amount Money) error {
// 加载聚合、校验领域规则、协调变更
}type Specification[T any] interface {
IsSatisfiedBy(T) bool
}
func And[T any](specs ...Specification[T]) Specification[T] { /* ... */ }
func Or[T any](specs ...Specification[T]) Specification[T] { /* ... */ }
func Not[T any](spec Specification[T]) Specification[T] { /* ... */ }type Specification[T any] interface {
IsSatisfiedBy(T) bool
}
func And[T any](specs ...Specification[T]) Specification[T] { /* ... */ }
func Or[T any](specs ...Specification[T]) Specification[T] { /* ... */ }
func Not[T any](spec Specification[T]) Specification[T] { /* ... */ }SetStatus()Place()Cancel()Ship()Reconstruct()var ErrNotFound = errors.New(...)Place()Cancel()Ship()SetStatus()Reconstruct()var ErrNotFound = errors.New(...)references/references/