Object-Oriented – Calling a Service Method from Another Service Method

netobject-orientedrepository

In the repository pattern, is it a "bad idea" to call a service method from another service method?

In most cases, I naturally end up calling repository methods from my service methods. However, in some cases, calling a service method from another service method seems to make sense because the existing service method nicely handles the task at hand.

Let's say I have the following methods:

GetUserFavoritesServiceMethod(userId, requestByUserId)
{
   // Make sure the request is allowed
   // This is the business logic where I make sure the requesting party is authorized to make the request

  // If allowed, call repository method
  var favs = GetUserFavoritesRepositoryMethod();
}

GetUserFavoritesRepositoryMethod(userId)
{
   // Return results
}

Now, let's assume I have another service methods that needs user favorites. I may be overly simplifying my example but this is where I have the option to call either the repository method or the existing service method.

GetSomeOtherInfoServiceMethod(userId, requestByUserId)
{
   // Call GetUserFavoritesServiceMethod() OR GetUserFavoritesRepositoryMethod()
}

Calling the GetUserFavoritesServiceMethods() seems a bit cumbersome because I may already be performing some business logic in the GetSomeOtherInfoServiceMethod() and performing business logic all over again in the GetUserFavoritesServiceMethod() seems bad/wasteful/etc.

On the other hand, the GetUserFavoritesServiceMethod() may be nicely packaging the data for me as opposed to GetUserFavoritesRepositoryMethod() may not be.

Again, I'm over simplifying it but clearly I'm adding some "value" in service methods and sometimes I want to take advantage of that "value".

I want to see if calling a service method from another service method is frowned upon in general.

Best Answer

You are facing a problem of an anemic domain model which leads to uncertainty about where to put "general" business logic which is unspecific to a usecase.

There are two types of business logic:

  1. usecase specific
  2. usecase unspecific

Watch this statements from Robert C. Martin:

OOP 2015 Keynote - Robert C. Martin ("Uncle Bob"): Agility and Architecture (26:55 to 28:22)

Robert C. Martin locates the usecase specific business logic into objects called "interactors". You also can say "usecases". Maybe "services" are a closely related so you may go on with that.

Entities will contain business logic that is not usecase specific. He also says that some developers call them "business objects" so I would do.

Whatever you call it: usecase specific and usecase unspecific business logic are different and have to be separated if you ask for advice. So an object of the domain model should be appropriate location to put the code of the method "getUserFavorites".

My suggestion is: user.getFavorites();