Java OO 静态实用方法求助!
我最近在 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我可能会创建某种 UserValidator 类并创建该类的实例来包含您的方法。
I would probably create some sort of UserValidator class and create an instance of that to contain your method.
首先,我不喜欢涉及创建新的
User
对象,然后对其调用checkUsername()
的解决方案,原因如下User
对象...因为它们不存在。这不是一个硬性规定,因为有时您可能需要一个User
对象来表示您要创建的用户或类似的用户,但在这里我发现它不自然。现在,我知道你在上课,所以这可能超出了你正在学习的内容,但更进一步:
这两种解决方案对我来说似乎都很好,因为两者都将使用它们的任何代码与数据库紧密耦合,使得代码难以测试。
对此的一般解决方案是将代码包装起来,这将使使用它的组件难以在接口中进行测试,如下所示:
然后您可以创建一个与数据库通信的 UserService 的实现,并且需要使用该代码的类可以在其构造函数中注入该代码的实现:
这就是依赖注入的原理。除了使您的代码更加灵活之外,它还允许您提供
UserService
的虚假实现以进行测试。如果你想测试当checkUsername
返回true
时某个类会发生什么,以及当它返回false
时会发生什么,你可以使用 fake 实现始终返回true
或始终返回false
。您不必担心设置数据库连接或确保存在正确的数据或确保测试后正确重置数据库状态,同样重要的是,当不需要执行数据库操作时,测试会快得多沟通。您可能想要做的介于两种方法之间的另一件事是拥有一个
User
对象来存储用户数据(但无法与数据库或任何此类事物本身进行通信)并将这样的方法放入您的UserService
中:此方法将为具有给定用户名的用户返回
User
对象(如果存在)并且null
否则。您还可以将checkUsername
实现为First off, I don't like the solution that involves creating a new
User
object and then callingcheckUsername()
on it for several reasons:User
object representing that user... because they don't exist. This isn't a hard and fast rule, since sometimes you might want aUser
object representing a user you're about to create or some such, but here I find it unnatural.new User()
and then havingcheckUsername()
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:
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: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 whencheckUsername
returnstrue
and what happens when it returnsfalse
, you can just use fake implementations that always returntrue
or always returnfalse
. 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 yourUserService
:This method would return the
User
object for the user with the given username if one existed andnull
otherwise. You could also implementcheckUsername
as just好吧,第二种方法更具可扩展性,也更直观(就您以后是否想更改内容而言),所以我推荐它。但第一种方法直接解决了问题,如果“用户”的概念以后不会被扩展(使用新方法),那么任何一种方法都应该没问题。
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.