德墨忒尔定律和 DAO 模式

发布于 2024-09-18 23:14:04 字数 380 浏览 6 评论 0原文

下面是我的 Spring/Hibernate 网站代码中的一个方法,它举例说明了我的代码库:

public class UserVoteServiceImpl implements UserVoteService {

   @Autowired UserRepository userRepository;

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

我认为该方法违反了 Demeter 定律,因为它调用 findUserById() 返回的对象。我如何更改此代码以遵守最少知识原则?

Here's 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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

懵少女 2024-09-25 23:14:04

我不认为这违反了德墨忒尔法则。如果您传入某个对象、从中获取 userId 并仅使用 userid,则将是违规的。

下面是一个违规的示例:

public class UserVoteServiceImpl implements UserVoteService {

   @Autowired UserRepository userRepository;

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

但是在方法的实现中委派工作并没有什么问题,并且对从存储库返回的对象进行调用也没有问题。

(就我个人而言,我并不热衷于使用服务来包装单个 dao 调用,但这是一个不同的问题。)

目前我正在开发一个由显然从未听说过 LoD 的人编写的代码库,其中充满了类似的东西

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

,最初我以为你的这个例子并没有达到与此相同的病理水平。但是在阅读这篇博文之后,当然,我就是从那里得到上面的例子的,
我想我建议您更改方法

public class UserVoteServiceImpl implements UserVoteService {

   @Autowired UserRepository userRepository;

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

并让调用者从用户那里获取分数。此更改还具有使应用程序的服务接口处理域对象而不是基元的好处。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文