代码之家  ›  专栏  ›  技术社区  ›  Brandon Yarbrough

德米特定律与道型

  •  2
  • Brandon Yarbrough  · 技术社区  · 15 年前

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

    public class UserVoteServiceImpl implements UserVoteService {
    
       @Autowired UserRepository userRepository;
    
       public static int getUserScore(long userId) {
         return userRepository.findUserById(userId).getScore();
       }
     }
    

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

    1 回复  |  直到 15 年前
        1
  •  1
  •   Nathan Hughes    15 年前

    我不认为这违反了德米特的法律。如果您传入某个对象,从中获取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);
    } 
    

    一开始我认为你的例子并没有上升到与那相同的病理水平。但读完之后 this blog post, which is where I got the above example, of course , 我想我建议你把方法改成

    public class UserVoteServiceImpl implements UserVoteService {
    
       @Autowired UserRepository userRepository;
    
       public User getUser(Long userId) {
         return userRepository.findUserById(userId);
       }
     }
    

    让来电者从用户身上扣下分数。这种更改还有一个好处,就是让应用程序的服务接口处理域对象,而不是原语。