Skip to content
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

Receiving ValueObject in Application Services methods parameters #57

Open
deploydesexta opened this issue Jan 15, 2025 · 3 comments
Open

Comments

@deploydesexta
Copy link

Hi Vaughn.

Have you considered using ValueObject in Application Service method parameters? It might help reduce the risk of errors. What do you think?

This:

    public void closeDiscussion(Tenant aTenantId, DiscussionId aDiscussionId) {
        Discussion discussion =
                this.discussionRepository()
                    .discussionOfId(aTenantId, aDiscussionId);

        discussion.close();

        this.discussionRepository().save(discussion);
    }

Instead this:

    public void closeDiscussion(String aTenantId, String aDiscussionId) {
        Discussion discussion =
                this.discussionRepository()
                    .discussionOfId(new Tenant(aTenantId),
                            new DiscussionId(aDiscussionId));

        discussion.close();

        this.discussionRepository().save(discussion);
    }
@100f
Copy link

100f commented Feb 23, 2025

Seems like trading six for half a dozen.
I think your intention here was to avoid calling closeDiscussion method with possible wrong parameters like null or empty strings, is that right?
The repository, however, being the domain object that it is, is always allowing only Value Object Ids in it's fetch method. You would have to instantiate TenantId and DiscussionId either way, you are just delegating the responsibility of creating those instances to elements further away from the application but the Ids themselves being value objects, should have these validation constraints intrinsically implemented anyway.

@VaughnVernon
Copy link
Owner

@100f I truly don't understand what you are asking or asserting. I'll take a few guesses.

  1. The tenantId and discussionId are passed in from the UI as strings. The domain model is type-safe and uses TenantId and DiscussionId types in all related parts of the domain model. Application Services are used as the glue between UI and model scenarios; the coordinate scenarios, which includes managing transactions.
  2. It is the responsibility of the Discussion to close itself when commanded to do so by a user in the proper role. The only way to get the Discussion to be closed is through the DiscussionRepository.
  3. DAOs are often used to carry out what should be business logic. A repository is not a DAO. If you leak business logic into a repository, you will lose business logic.

I get the impression that you have not read my book "Implementing Domain-Driven Design." All the intricacies demonstrated by the code are covered in 14 detailed chapters, ad nauseum.

@100f
Copy link

100f commented Feb 23, 2025

@VaughnVernon This answer should be addressed to the OP, not me. I actually answered him that there is no need to pass the primitive values of TenantId and DiscussionId to a repository method, because as a domain object, the repository should speak domain, which is exactly what is already being done in

  Discussion discussion =
                  this.discussionRepository()
                      .discussionOfId(new Tenant(aTenantId),
                              new DiscussionId(aDiscussionId));

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants