Java中静态数据库工厂方法的替代方法
我一直在阅读Java中的静态与实例方法(特别是因为我在单元测试中遇到了难点),并试图找出如何编写与数据库交互的工厂。我知道有很多相关的问题;但我的具体案例似乎非常普遍,如果能了解DB工厂的替代方案,那就太好了。我目前的做法(附带一个常见用例的简化示例): 这允许我使用Java中静态数据库工厂方法的替代方法,java,jdbc,instance,static-methods,instance-methods,Java,Jdbc,Instance,Static Methods,Instance Methods,我一直在阅读Java中的静态与实例方法(特别是因为我在单元测试中遇到了难点),并试图找出如何编写与数据库交互的工厂。我知道有很多相关的问题;但我的具体案例似乎非常普遍,如果能了解DB工厂的替代方案,那就太好了。我目前的做法(附带一个常见用例的简化示例): 这允许我使用User User=UserFactory.getUser(1)获取一个用户。但是,我不能嘲笑它,除非我使用类似的东西,这使得测试更烦人。另外,许多人认为编写代码是这样的。 另一种选择可能是: public class UserFa
User User=UserFactory.getUser(1)获取一个用户代码>。但是,我不能嘲笑它,除非我使用类似的东西,这使得测试更烦人。另外,许多人认为编写代码是这样的。
另一种选择可能是:
public class UserFactory {
// ** This class is identical to the class
// above except this method is not static. **
public User getUserById(Integer userId) throws SQLException {
Connection c = null;
PreparedStatement stmt = null;
ResultSet rs = null;
User user = null;
try {
c = ConnectionFactory.getConnection(); // Uses java.sql.DriverManager to get a connection to our DB
stmt = c.prepareStatement(STATEMENT);
stmt.setInt(1, userId);
rs = stmt.executeQuery();
if (rs.next()) {
user = new User();
// Set user properties
}
} finally {
ConnectionFactory.closeConnection(c, stmt, rs); // Calls .close() on c, stmt and rs
}
return user;
}
}
要现在获得一个用户,我必须执行类似于User User=new UserFactory().getUser(1)代码>。当然,我可以实例化一个UserFactory
对象并重用它(我甚至可以传递它和/或将它注入到其他类中;但我们经常与各种这样的工厂交互,因此在许多情况下,我们需要在许多工厂中注入/传递,这似乎很笨拙):
这将使测试变得简单(例如,使用),因为我可以只创建一个UserFactory
的模拟实例(我想这意味着newuserfactory().getUser(1)
示例用法不会很有帮助——我需要将一个实例传递给我正在测试的任何对象,对吗?)。似乎没有必要使用UserFactory
的实例来实现我的目标(从数据库中检索用户),但我喜欢它使测试更容易(不希望单元测试击中数据库)
我错过了什么?我没有考虑的其他选择和优点/缺点是什么?我目前的做法是一种“糟糕”的做法,仅仅是因为它使测试变得烦人还是出于其他(更重要的)原因?我真的建议查看尝试使用资源,使您的代码更干净,而不需要最后的块。@Nexevis,这很酷!我不知道那是件事。我得进一步调查一下--谢谢!非常方便的是,连接
,准备语句
(通过语句
)和结果集
都扩展了自动关闭
。在某一点上可能需要进行更多的重构:d我希望的设计类似于:接口UserFactory{…}
,类userfactorympl实现UserFactory{public userfactorympl(ConnectionFactory ConnectionFactory){…}
,也就是说,ConnectionFactory
还应该基于实例方法,而不是静态方法,并且ConnectionFactory
应该在创建时传递到UserFactory
。(它也应该有一个接口/实现对。)我真的建议您研究并尝试使用资源,以使您的代码更干净,而不需要最终块。@Nexevis,这很酷!我不知道那是件事。我得进一步调查一下--谢谢!非常方便的是,连接
,准备语句
(通过语句
)和结果集
都扩展了自动关闭
。在某一点上可能需要进行更多的重构:d我希望的设计类似于:接口UserFactory{…}
,类userfactorympl实现UserFactory{public userfactorympl(ConnectionFactory ConnectionFactory){…}
,也就是说,ConnectionFactory
还应该基于实例方法,而不是静态方法,并且ConnectionFactory
应该在创建时传递到UserFactory
。(它也应该有一个接口/实现对。)
public class UserFactory {
// ** This class is identical to the class
// above except this method is not static. **
public User getUserById(Integer userId) throws SQLException {
Connection c = null;
PreparedStatement stmt = null;
ResultSet rs = null;
User user = null;
try {
c = ConnectionFactory.getConnection(); // Uses java.sql.DriverManager to get a connection to our DB
stmt = c.prepareStatement(STATEMENT);
stmt.setInt(1, userId);
rs = stmt.executeQuery();
if (rs.next()) {
user = new User();
// Set user properties
}
} finally {
ConnectionFactory.closeConnection(c, stmt, rs); // Calls .close() on c, stmt and rs
}
return user;
}
}
UserFactory userFactory = new UserFactory();
User user = userFactory.getUser(1);