Java Reference
In-Depth Information
For our purposes, we will look at what is required to accomplish the first two
tiers, but for transaction and connection management, you will need to refer to
chapter 7, and go from there.
11.4.1
Separating interface from implementation
The reason you want to separate your
DAO
into an interface and an implementa-
tion is twofold. First, you want to be able to replace the implementation if you
have to support a different type of data access. Second, separation makes testing
much simpler and faster because you can plug in a mock
DAO
instead of working
with the database.
If you use an
IDE
, you may think that this is going to be the easiest part of the proc-
ess. With most development environments, you have a refactoring tool to extract an
interface from the class. However, that is only a small part of the process.
If you are just getting started with the
DAO
pattern, it is likely that your inter-
face is exposing classes specific to
JDBC
, i
BATIS
, or some other tool for dealing
with your database. That is the part of the interface that is more difficult to man-
age. This creates a problem because it binds more of your application to the data
access implementation than just the
DAO
. Although it is not a huge difficulty, it is
not a trivial matter either.
Changing code that uses a result set to use a collection (such as a List of beans)
is straightforward, but as with any change, it will require testing, and depending
on where the code is located in your application, the process can be challenging.
For example, if you have a web application that uses a “Fast Lane Reader” pattern
to provide lightweight reporting over large data sets, your
JDBC
code may interact
directly with the view layer. This can be very difficult to test, because anything
requiring human interaction takes more time. In addition, it may be difficult to
rewrite in a way that performs as well as the original. One solution is to write the
code using callbacks to speed up the data access (so, in this example, you may
want to consider a
RowHandler
that responds to view requests for data).
Changing applications that directly access the
SQL
Map
API
to access a more
encapsulated
API
is a reasonably trivial matter. For example, if you are developing
a class that calls
queryForList()
on a
SqlMapClient
object, you simply need to
refactor that call into your
DAO
class, and then return the List object from it so
that your data consumer only talks to your
DAO
.
11.4.2
Decoupling and creating a factory
So, now that we have separated the interface and implementation, we do not want
to introduce both of those into our classes that use the
DAO
, because instead of
