views:

707

answers:

3

In this question someone replies "You never let the domain object implementations call services by themselves!". Is this statement a hard fast rule of DDD or does it depend on your own application and architecture?

Contrived example:

As an example lets suppose we have a UserImage object in our model that gets populated from an uploaded image by a user. And then lets suppose that we can submit this image to a 3rd party service that can identify thumb prints and return an Guid if a match is found.

public IThumbPrintService
{
    Guid FindMatch(Bitmap image);
}

public class UserImage
{
    public Bitmap Image {get; set;} 
    public Guid ThumbPrintId {get; set;}

    public bool FindThumbPrintMatch()
    {
       // Would you call the service from here?
       ThumbPrintId = _thumbPrintService.FindMatch(this.Image);

       return ! ThumbPrintId.CompareTo(Guid.Empty);
    }
}

public class RoboCopUserImageService : IUserImageService
{
     // Or move the call to a service method 
     // since it depends on calling a separate service interface
     public bool FindThumbPrintMatch(UserImage userImage)
     {
        userImage.ThumbPrintId = _thumbPrintService.FindMatch(userImage.Image);

        return !userImage.ThumbPrintId.CompareTo(Guid.Empty);            
     }
}

What is avoided or gained by not letting domain objects call services themselves?

EDIT: are there any good online articles which discuss this specific topic?

A: 

One disadvantage I see is that allowing your domain object to call services may make it harder to serialize, or at least cause some issues after serializing it when someone on the other side calls its service method(s).

Otávio Décio
A: 

If you allow an Entity Object to call a service it is performing two roles Data Object and Service Object. Generally, each object should have on responsibility, not only in implementation but also in usage.

In your case, the lowly UserImage seems to be both an Image and a ThumbPrint Recognizer.

Allain Lalonde
The example was made up on the spot. The real question is should your domain objects call services or not and the Spreadsheet Conundrum problem pretty much hits the nail on the head. It depends!
Todd Smith
Thank you for clearing up your answer. What if your Entity Object has a method such as Account.Debit(amount) which needs to make use of a service to complete the action (ex: update a repository, call a validation service, or send a notification)?
Todd Smith
It'd handle that by having the AccountService accept a simple Account object as an argument to a debit method.
Allain Lalonde
+17  A: 
moffdub
Thanks, the Spreadsheet Conundrum makes this problem much clearer now. I also like how you suggest verbalizing the problem to domain experts to determine which approach makes more sense.
Todd Smith
Wow, brilliant answer, very clear, very detailed. I'd like to give you more than one up vote !
Guillaume
Thanks for the praise. The content of this answer is really a synthesis of the effects of my undiagnosed OCD. The questions that DDD and OO raise never fail to fascinate me.
moffdub