3

Say I have a shipping service where I have both a driver and a dispatcher, but there are multiple roles and a user can belong to more than one role. Both the driver and dispatcher roles can mark a delivery as delivered, but a driver can only mark deliveries completed if they're assigned to those deliveries while a dispatcher can mark any deliveries completed so long as they're being delivered by their shipping company. In the application service (in a domain driven design sense) should you have separate methods for each of these actions e.g. completeDeliveryAsDispatcher and completeDeliveryAsDriver. This seems to make for much cleaner service methods because now I don't need to try to figure out what type of user I'm dealing with.

1 Answer 1

5

No, you should not. You should handle the logic for different roles within the method. In your example there will be one exposed method:

pubic void completeDelivery(User user) { ... }

There are a number of reasons for that:

  • Relying on the user to use your service responsibly is inviting someone to behave badly
  • It consolidates all the places that need to be updated if the requirements change based on roles
  • You don't have to change the public interfaces if a role is added, removed, or simply changed

If you want to delegate to internal methods that consolidate all the logic for a particular role, that's up to you. It's just not part of the public service interface.

4
  • That seems reasonable, but I'm still unclear what should then be happening at the domain layer. Should there be separate actions for completeDeliveryAsDispatcher or even just completeAssignedDelivery there? If not where I am I doing the check to validate assignment - in a domain service? The reality is that I don't really need to be aware of the "role" or "actor" until this point because with the previous checks I can simply check if they have the permission to update any trips or update only assigned trips.
    – Jordan
    Commented Nov 22, 2019 at 14:51
  • I was looking at this for inspiration, but it doesn't really deal with cases where there is more than one user that can do a particular action: github.com/VaughnVernon/IDDD_Samples/blob/master/… .. if I were to make the driver an optional argument in the domain model completeTrip method I'd be relying too much on the caller to have knowledge of the business logic around assignment
    – Jordan
    Commented Nov 22, 2019 at 14:55
  • Keep in mind that my window into your application is as large as your question. The question you asked is whether you should have xxxAsRole() style functions at the service layer. The very first bullet relates to security. The other bullets relates to the maintainability of your code. You simply need the information passed in to your function that it needs to complete its logic. If there is another way to get the user's role in that context, use it. At the end of the day, I'm not the one maintaining this application. Commented Nov 22, 2019 at 20:51
  • Just make the best informed decisions you can, even if they don't agree with me. Understand your trade-offs. There are times I go against the commonly spouted "best practices", and I have the experience to understand when it's OK or an acceptable risk. Commented Nov 22, 2019 at 20:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.