【问题标题】:Java OO static ultility method help!Java OOP 静态实用方法求助!
【发布时间】:2010-12-14 22:32:50
【问题描述】:

我最近在 User 类中做了一个方法,看起来像这样;

  public static boolean checkUN(String username) {
  boolean check = false;
  ResultSet rs;
  String dbQuery;
  SQLController db = new SQLController();
  db.setUp();
  dbQuery = "SELECT * FROM User WHERE User_name ='" + username + "'";
  try {
   db.setUp();
   rs = db.readRequest(dbQuery);
   if (rs.next()) {
    check = true;
   }
  } catch (Exception e) {
   e.printStackTrace();
  }
  db.terminate();
  return check;
 }

我打算在用户能够继续进行下一步注册之前进行验证检查。

我拿给老师看的时候,她说没关系,因为我用它作为一个实用的方法。不过后来她改变了主意,说我应该把它改成一个实例方法,然后创建一个新的 User 对象来做验证。

哪种方式更有效?

user.checkUsername(jTextUN.getText());

和实例方式 (假设我改变了方法,去掉了静态和输入参数);

User user = new User();
user.setUsername(jTextUN.getText());
user.checkUsername();

干杯!

【问题讨论】:

    标签: java methods static instance


    【解决方案1】:

    我可能会创建某种 UserValidator 类并创建一个实例来包含您的方法。

    【讨论】:

      【解决方案2】:

      首先,我不喜欢涉及创建一个新的User 对象然后在其上调用checkUsername() 的解决方案,原因如下:

      • 如果不存在具有给定用户名的有效用户,则不应有任何代表该用户的User 对象...因为它们不存在。这不是一个硬性规定,因为有时您可能需要一个 User 对象来代表您将要创建的用户或类似的对象,但在这里我觉得它不自然。
      • 它违反了对数据对象可以做什么的期望。创建一个new User(),然后让checkUsername() 根据给定用户的用户名返回不同的值,这将是令人惊讶的。

      现在,我知道你正在上课,所以这可能超出你所学的范围,但更进一步:

      这两种解决方案对我来说似乎都不是很好,因为两者都将使用它们的任何代码紧密耦合到数据库,使得该代码难以测试。

      对此的一般解决方案是包装代码,这会使使用它的组件难以在接口中进行测试,如下所示:

      public interface UserService {
        boolean checkUsername(String username);
        ...
      }
      

      然后您可以创建与数据库对话的UserService 的实现,并且需要使用该代码的类可以在其构造函数中注入它的实现:

      public class UserServiceClient {
        private final UserService userService;
      
        public UserServiceClient(UserService userService) {
          this.userService = userService;
        }
      
        ...
      }
      

      这就是依赖注入的原理。除了使您的代码更加灵活之外,它还允许您提供 UserService 的虚假实现以进行测试。如果你想测试当checkUsername返回true时某个类会发生什么以及当它返回false时会发生什么,你可以使用总是返回true或总是返回false的假实现。您不必担心设置数据库连接或确保存在正确的数据或确保在测试后正确重置数据库状态,同样重要的是,当不需要执行数据库时,测试要快得多交流。

      您可能想做的另一件事介于这两种方法之间,那就是拥有一个 User 对象来存储用户的数据(但不能与数据库或任何此类事物本身进行通信)并在您的UserService 中添加这样的方法:

      User getUser(String username);
      

      此方法将为具有给定用户名的用户返回User 对象(如果存在),否则为null。你也可以实现checkUsername 就像

      return getUser(username) != null;
      

      【讨论】:

      • 我认为这种模式应该用于创建一个数据库接口的实现,其中包含方法 open()、close()、isOpened()、query() 等,因为有一天你可以改变你数据库适配器,并且您可能不想更改使用数据库的其余类。如您所说,如果您应用此技术来获取有关用户的信息,这对于测试目的是有好处的,但是您可能只会在创建方法时测试一次方法。因此,使用依赖注入设计可能会毫无意义地增加您的类数量。看我的回答。
      • ..continue 该类 (UserHelper) 正在使用数据库实现(使用 DatabaseFactory.createDatabase() 方法创建),它覆盖 open()、close() 等方法。想一想。
      • @GagleKas:不...您的答案涉及在不需要时将代码紧密耦合到数据库。一个依赖注入解决方案,其代码(在生产中)与隐藏在接口后面的数据库进行对话,使以后更改实现该服务的方式变得非常更容易,因为您只需要创建一个新的实现和将其连接到需要它的客户端。您不需要更改任何现有的类。我不太确定你在说什么关于数据库接口,因为 JDBC、JPA 等已经提供了数据库抽象。
      • 嗯,对,就是你说的,客户端使用接口来使用数据库。
      【解决方案3】:

      嗯,第二种方式更可扩展且更直观(就您以后是否想更改而言),所以我推荐它。但是第一种方法直接解决了问题,如果以后不扩展“用户”的概念(使用新方法),那么任何一个都可以。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-10-04
        • 2011-11-10
        • 2018-10-04
        • 1970-01-01
        • 1970-01-01
        • 2017-06-22
        相关资源
        最近更新 更多