Darshan penned
> There is one post at theserverside.com forum(thread #14864) , which
> tells that as long as you pass the connection object from the caller
> as a param
> to the static method in DAO and the DAO is not using any other class
> level variables, it should be fine. (?)
Yes, that will solve the problem of static methods sharing resources or
state variables, but that's not really the problem with this approach in
this case.
Taking a simple example, you have a UserDao with these static methods:
Collection findAll ( )
User findByEmail ( String email )
User create ( )
void update ( User user )
void delete ( Integer id )
An example DAO client might look like
public boolean login ( String email , String password ) {
User user = UserDao.findByEmail(email);
return password.equals(user.getPassword());
}
You build it using JDBC and end up using a few Oracle-specific features
(examining error codes and using a sequence for generating User IDs).
Now your boss says, "Oracle is too expensive. Port the DAO to MySQL. Oh,
and by the way, in the interim we need to be able to switch between
Oracle and MySQL at runtime via a property." What now?
public boolean login ( String email , String password ) {
User user;
String flavor = System.getProperty("dao.flavor");
if ( flavor.equals("Oracle") )
User user = UserDaoOracle.findByEmail(email);
else if ( flavor.equals("MySQL") )
User user = UserDaoMySQL.findByEmail(email);
else
throw new ConfigurationException("Unknown DAO flavor");
return password.equals(user.getPassword());
}
And when you switch from JDBC to Hibernate? And as Tareq mentioned, if
you want to unit test the DAO clients in isolation, you'll want to use a
mock DAO. So you add another
else if ( flavor.equals("mock") )
User user = UserDaoMock.findByEmail(email);
Except trying to use a mock static object would be a PITA. The first
step would be to make a non-static interface and a static class that
delegates to the interface, to be implemented by jMock or EasyMock or
whatever.
If you instead make the DAO non-static, you can simply create and assign
a DAO instance of whatever flavor you need to your client objects. If
you were using Spring, this would be a simple change to the class name
of the DAO bean in an XML file. Without that, you can put the DAO class
to instantiate in your configuration file and use it exactly one time at
startup.
In your bootstrap (system setup) code:
String daoClassName = System.getProperty("user.dao.class");
UserDao dao = (UserDao) Class.forName(daoClassName);
daoClient.setUserDao(userDao);
And your new client code:
private UserDao userDao;
public boolean login ( String email , String password ) {
User user = userDao.findByEmail(email); // member, not static class
return password.equals(user.getPassword());
}
To summarize, by using static methods you are painting yourself into a
corner and making your life hard for no good reason. You don't even need
to create an interface to start if you don't want, but by all means make
it a non-static class!
Spring is ideal for easing the pain of bootstrapping your business
objects by wiring them together with XML instead of Java code and
properties files. Even without it, though, you gain a lot by using
non-static classes.
--
David Harkness Sony Pictures Digital
Sr. Software Engineer 310.482.4756 dharkness@(protected)
A "No" uttered from deepest conviction is better and greater than a
"Yes" merely uttered to please, or what is worse, to avoid trouble.
-- Mahatma Ghandi
====================================================================
Companion Site: http://www.corej2eepatterns.com
J2EE BluePrints: http://java.sun.com/blueprints/corej2eepatterns
List Archive: http://archives.java.sun.com/archives/j2eepatterns-interest.html
Unsubscribing: email "signoff J2EEPATTERNS-INTEREST" to listserv@(protected)