开发者

Law of Demeter and DAO pattern

开发者 https://www.devze.com 2023-01-16 02:28 出处:网络
Here\'s开发者_JAVA技巧 a method in my Spring/Hibernate website\'s code that exemplifies my codebase:

Here's开发者_JAVA技巧 a method in my Spring/Hibernate website's code that exemplifies my codebase:

public class UserVoteServiceImpl implements UserVoteService {

   @Autowired UserRepository userRepository;

   public static int getUserScore(long userId) {
     return userRepository.findUserById(userId).getScore();
   }
 }

I believe that this method violates the Law of Demeter, since it is making calls on the object returned by findUserById(). How can I change this code to obey the Principle of Least Knowledge?


I don't think it's a violation of the Law of Demeter. It would be a violation if you were passing in some object, getting userId off of it, and using only the userid.

Here's an example that would be a violation:

public class UserVoteServiceImpl implements UserVoteService {

   @Autowired UserRepository userRepository;

   public static int getUserScore(SomeWrapper someWrapper) {
     return userRepository.findUserById(someWrapper.getUserId()).getScore();
   }
 }

But there's nothing wrong with delegating work within the implementation of your method, and there's nothing wrong with making a call on the object returned from the repository.

(Personally I'm not crazy about using services to wrap single dao calls, but that's a different problem.)

Currently I'm working on a codebase perpetrated by people who apparently never heard of LoD, full of stuff like

public Thing getThing(Integer id) {
    return new Beta().getGamma().getDelta().getEpsilon().getOmega().getThing(id);
} 

and initially I thought your example didn't rise to the same level of pathology as that. But after reading this blog post, which is where I got the above example, of course, I think I'd recommend you changing your method to

public class UserVoteServiceImpl implements UserVoteService {

   @Autowired UserRepository userRepository;

   public User getUser(Long userId) {
     return userRepository.findUserById(userId);
   }
 }

and letting the caller pull the score off the User. This change also has the benefit of having the application's service interface deal in domain objects, not in primitives.

0

精彩评论

暂无评论...
验证码 换一张
取 消