首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么“Manager”类中的“getter”方法不应该是静态的?

为什么“Manager”类中的“getter”方法不应该是静态的?
EN

Stack Overflow用户
提问于 2016-06-27 23:56:09
回答 3查看 943关注 0票数 1

在大多数情况下,传统的编程智慧似乎阻碍了静态方法的使用。通常,我有这些“经理”,例如UserManager,AppointmentManager e.t.c。管理器中的方法之一总是XXX getXXX(long xxxId),例如User getUser(long userId)。我真的不明白为什么这不能是一个静态的方法。它看起来非常像一个工厂方法( la GoF工厂模式)。很难放弃以下便利:

User user = UserManager.getUser(id);

并使用

UserManager userManager = new UserManager(); User user = userManager.getUser(userId);

而不是。

我相信测试,我只是不是一个“模拟测试”的粉丝,所以我需要的理由除了嘲笑。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2016-06-28 00:09:28

避免对象工厂中的静态方法的主要原因是保持状态的能力。虽然静态方法可以将它们的状态保持在静态字段中,但是这种方法很难保存和重置工厂的状态。

此外,不可能对工厂的接口进行编程,因为静态方法不能用作接口实现。当您需要透明地将对象的实现切换到应用程序的其他部分时,这一点变得非常重要。

最后,静态方法增加了测试代码的难度,不管是否使用了模拟。您的测试将很难验证您的工厂的某些方法是按特定顺序调用的。

票数 6
EN

Stack Overflow用户

发布于 2016-06-28 00:45:15

我认为Bob叔叔在他的清洁代码书中解释这个问题做得很好(顺便说一句,很棒)。但是无论如何,他的观点是,您不应该在任何想要利用多态性的地方使用静力学(我认为这正是您在上述情况下所想要的)。

在您的例子中,您有一个UserManager。绝不是一个完整的申请,对吧?您可能有一些使用UserManager的更复杂的东西。假设您有自己的StackOverflow版本(当然,不要这样做,堆栈溢出是很棒的,不需要竞争)。

好的,我们有一个调用LoginService ()的UserManager.getUser()。这是一个不可改变的依赖关系(因为我们没有利用多态性)。如果UserManager.getUser()需要底层的SQL数据库,那么猜猜您需要运行(或测试)LoginService.SQL数据库!

代码语言:javascript
复制
public class LoginService {
   public boolean authenticate(String username, String password) {
      User user = UserManager.getUser(username); // hard dependency on implementation
      // other stuff
   }
} 

更普遍的解决方案是抽象出可以在接口后面更改的内容。这样,您就可以交换实现。LoginService有一个应该测试的任务,实际上不应该依赖于特定的数据库实现。

代码语言:javascript
复制
public interface UserManager {
   User getUser(String id):
}

public class SQLUserManager implements UserManager {
   @Override
   public User getUser(String id) { // SQL stuff }
}

class LoginService {
   public LoginService(UserManager userManager) {
      this.userManager = userManager;
   }

   public boolean authenticate(String username, String password) {
      User user = userManager.getUser(username);
      // other stuff
   }
} 

现在,LoginService可以独立于使用什么UserManager进行测试,如果用户实现发生变化,则可以单独进行测试。

这不是模拟,而是测试您的组件,而不需要设置整个应用程序堆栈。

票数 1
EN

Stack Overflow用户

发布于 2016-06-28 00:45:24

通常不鼓励静态地保持状态,而倾向于使用依赖注入。如前所述,静态方法无法实现接口。使用静态使类不可能有多个实例。

如果您需要两个不同的用户管理器,指向不同的数据源,则必须进行主要的重构。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38064993

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档