-
Notifications
You must be signed in to change notification settings - Fork 456
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Couple of ideas #16
Comments
I'm playing with the idea of first (above the line) vs second (blow the line) // Repository knows how to persist the service's aggregate
type Repository interface {
// Add knows how to create an initialized instance of an aggregate
// it expects an initialized instance be return from an add funcion or nil to bail out
Add(ctx context.Context,f func() (*account.Account)) (uuid.UUID, error)
// Add knows how to remove an identifiable instance of an aggregate
// it also returns a copy to a remove funtion in order to bail out
Rem(ctx context.Context, i Identifiable, f func(a account.Account) bool) error
// Update knows how to update an identifiable instance of an aggregate
Update(ctx context.Context, i Identifiable, f func(a *account.Account) bool) error
}
// Identifiable can be identified by the Repository
type Identifiable interface {
// Identifer knows how to identify an object
Identifier() uuid.UUID
} // Store knows how to read and write an entity
type Store interface {
// Load knows how to load an entity
Load(ctx context.Context, uuid uuid.UUID) (a *account.Account, err error)
// Save knows how to save an entity
Save(ctx context.Context, a *account.Account) error
}
// Identifiable can be identified so that the store can load it
type Identifiable interface {
// Identifer knows how to identify an object
Identifier() uuid.UUID
} The latter approach has several benefits in my eyes:
// cave: pseudo-code ...
func(h *DoSomethingHandler) Handle(ctx context.Context, ds DoSomething) error {
old, err := Load(ctx, ds.Identifier())
new := old.Copy()
...
ok := h.pol.Can(ctx, ds, "DoSomething", new) // check policy
if err = h.handle(ctx, new); err != nil { // handle domain logic
return errwrap.Wrap(ErrInDomain, err)
}
if err = Save(ctx, new); err != nil { // nil to delete
return errwrap.Wrap(ErrDuringSave, err)
}
...
err = Publish(ctx, &SomethingDone{...})
if err != nil {
Save(ctx, old)
}
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
While continuing to work on
ddd-gen
(example) I had a couple of ideas / made a couple of choices worth sharing here:Add
andRemove
as well, so that the domain does not need to know about the behaviour of the repository interface (that only works on an aggregate)Identifiable
s to the repository so that the auto generated code does not need to know too much about the commands data structures, while still verifying identifiability of the object (domain aggregate) on which the command should be executed.→ Repo Interface
The text was updated successfully, but these errors were encountered: