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.
精彩评论