Java OO 静态实用方法求助!

发布于 2024-10-07 23:59:04 字数 845 浏览 3 评论 0原文

我最近在 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();

干杯!

I recently did a method in the User class which looks like this;

  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;
 }

I intended it to be a validation check before the User is able to continue to the next step of registration.

When I showed it to the teacher, she said that it would be ok, as im using it as a ultility method. However, she changed her mind later on, saying that I should change this to an instance method, then creating a new User object to do the validation.

Which way is more effective?

user.checkUsername(jTextUN.getText());

and the instance way
(assuming I changed the method, removing static and the input parameter);

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

Cheers!

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

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

发布评论

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

评论(3

少跟Wǒ拽 2024-10-14 23:59:04

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

I would probably create some sort of UserValidator class and create an instance of that to contain your method.

看轻我的陪伴 2024-10-14 23:59:04

首先,我不喜欢涉及创建新的 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 时会发生什么,你可以使用 fake 实现始终返回 true 或始终返回 false。您不必担心设置数据库连接或确保存在正确的数据或确保测试后正确重置数据库状态,同样重要的是,当不需要执行数据库操作时,测试会快得多沟通。

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

User getUser(String username);

此方法将为具有给定用户名的用户返回 User 对象(如果存在)并且 null 否则。您还可以将 checkUsername 实现为

return getUser(username) != null;

First off, I don't like the solution that involves creating a new User object and then calling checkUsername() on it for several reasons:

  • If no valid user exists with a given username, you shouldn't have any User object representing that user... because they don't exist. This isn't a hard and fast rule, since sometimes you might want a User object representing a user you're about to create or some such, but here I find it unnatural.
  • It violates expectations about what data objects can do. Creating a new User() and then having checkUsername() return different values depending on what username that user is given would be surprising.

Now, I know you're in a class and so this may go beyond what you're learning, but to go even further:

Neither solution seems very good to me because both tightly couple any code that uses them to the database, making that code difficult to test.

The general solution to this is to wrap the code that would make components that use it difficult to test in an interface, something like this:

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

Then you can create an implementation of UserService that talks to the database, and classes that need to use that code can have an implementation of it injected in their constructors:

public class UserServiceClient {
  private final UserService userService;

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

  ...
}

This is the principle of dependency injection. In addition to just making your code more flexible, it allows you to provide fake implementations of UserService for testing. If you want to test what happens in a certain class when checkUsername returns true and what happens when it returns false, you can just use fake implementations that always return true or always return false. You don't have to worry about setting up database connections or ensuring that the right data is present or ensuring that the database state is properly reset after a test, and equally importantly a test is far faster when it doesn't have to do database communication.

Another thing you might want to do that falls somewhere in between the two approaches would be to have a User object that stores data on a user (but can't communicate with the database or any such thing itself) and to put a method like this in your UserService:

User getUser(String username);

This method would return the User object for the user with the given username if one existed and null otherwise. You could also implement checkUsername as just

return getUser(username) != null;
凤舞天涯 2024-10-14 23:59:04

好吧,第二种方法更具可扩展性,也更直观(就您以后是否想更改内容而言),所以我推荐它。但第一种方法直接解决了问题,如果“用户”的概念以后不会被扩展(使用新方法),那么任何一种方法都应该没问题。

Well, the second way is more extensible and more intuitive (in terms of if you want to change things later on), so I'd recommend it. But the first way solves the problem directly, and if the concept of a "user" won't be extended later (with new methods), then either one should be fine.

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