Spring服务类包含太多的finder方法

时间:2014-04-20 04:59:39

标签: java spring service spring-data-jpa

我使用Spring框架和Spring Data JPA来开发应用程序。下面是存储库接口和服务类之一。

public interface UserRepository extends JpaRepository<User, Long>
    User findByName(String name);
    User findByEmail(String email);
}

public class DefaultUserService implements UserService {
    @Inject protected UserRepository userRepo;

    @Override
    public User getUserById(Long id) {
        return userRepo.findOne(id);
    }

    @Override
    public User getUserByName(String name) {
        return userRepo.findByName(name);
    }

    @Override
    public User getUserByEmail(String email) {
        return userRepo.findByEmail(email);
    }
}

正如许多专家所说,服务层设计应该是粗粒度的,并专注于应用程序操作。看看上面的服务类,我认为这不是一个好的设计,因为它直接暴露了存储库中的所有finder方法。由于上面的所有3种服务方法都返回相同的对象类型(User),我希望只公开一种finder方法,而不是三种能够封装所有finder逻辑的方法。

public class DefaultUserService implements UserService {
    @Inject protected UserRepository userRepo;

    // what would be the arguments and logic for this method.
    @Override
    public User getUser() {
    }
}

如果有人能指出如何解决这个设计问题的解决方案,我感激不尽?

1 个答案:

答案 0 :(得分:1)

我认为设计并不是那么糟糕,我的意思是我多次看到这种方法,实际上你有几种finder方法,但每一种都使用不同的属性来获取User,如果你想制作一个服务方法它封装了用于检索用户的逻辑,我建议这样做。

public class DefaultUserService implements UserService {
    @Inject protected UserRepository userRepo;

    enum UserFindEnum{
        ID, EMAIL, NAME;
    }

    public User getUser(UserFindEnum e, Object obj){
        switch(e.ordinal()){
            case 0:
                return userRepo.findOne(obj);
            case 1:
                return userRepo.findByName(obj);
            case 2:
                return userRepo.findByEmail(obj);
            default:
              break;
        }
    }
}

我的意思是你需要知道你将使用哪个属性来查找用户,因此至少需要将一个参数发送到服务层,因此getUser()这还不够。可能使用上面的某种逻辑,你将只有一种服务方法和所需的逻辑。