| By Mike Barlotta | Article Rating: |
|
| September 1, 2002 12:00 AM EDT | Reads: |
15,683 |
In Part 1 (JDJ, Vol. 7, issue 6) we looked at the Java class as a type. Although it's easy to think of the class name of our Java class as its type, the interfaces it implements and the superclasses it extends can also be viewed as its types.
In Part 2 I'll explore using interfaces and abstract classes to achieve flexibility with a real-world example that implements the Data Access Object (DAO) pattern. I'll also quickly look at the abstract classes and interfaces in the Java arena.
Putting It to Real Use the DAO Pattern
Data can be stored in different persistent data sources. These include
relational databases as well as flat files, XML documents, LDAP, and legacy
systems. Each data source requires a different way of getting a connection
to it as well as various ways of retrieving, adding, updating, and removing
data. With the DAO pattern you can separate the data source access and
encapsulate interaction with the data from objects that use the data.
In any given application we may have a defined business entity called Customer. Rather than code all the data access logic in the Customer object, we'd want to separate this because the business that needs the application may store data for its customers in different databases. Some of the data may even be in legacy systems that require lots of code written with a proprietary API to get the data out. Keeping the data access logic out of the Customer business object makes the code cleaner and allows the developer to focus on the business needs instead of how to get the data.
Another practical use for the DAO pattern would be a product company that wants their application to work with multiple relational databases, allowing customers to use the DBMS of their choice. In either case we would want to use the DAO pattern to encapsulate data access from the rest of our application.
We can create a flexible implementation of this pattern using an abstract class and an interface. For example, a company has an application that needs to get customer data from either an Oracle or a Microsoft SQL Server DBMS. Because the SQL syntax for the Oracle and the Microsoft DBMS are not compatible, we'll need to write a separate class that can access the customer data from either database. These classes are represented by the OracleCustomerDAO and the MSSQLCustomerDAO. Because the set of methods for each of these objects is the same (get, add, update, delete) but they don't share any common implementation, we'll define an interface CustomerDAO as follows:
public interface CustomerDAO {
public CustomerDatagetCustomer
(String id);
public StringaddCustomer
(CustomerData cd);
public booleanupdateCustomer
(CustomerData cd);
public boolean deleteCustomer(Stringid);
}
The OracleCustomerDAO and the MSSQLCustomerDAO would implement each method using the specific SQL syntax of the DBMS to perform the operations.
The CustomerData object encapsulates all the data about our Customer. This class typically uses Java fields to hold the data and has no methods (other than accessor get/set methods). This is an example of the Value Object pattern.
Next we need to consider how to allow the application to get the proper CustomerDAO implementation without each class that needs customer data trying to determine which database is in use. Since this is a common operation, we can place that logic in a separate class that will then create the proper CustomerDAO object. This is called a factory.
Since the Oracle and Microsoft databases require different classes for each business entity we want to access (e.g., Customer, Order, etc.), we'll create a separate factory for each. The OracleDAOFactory class will have a getCustomerDAO method on it that will return a copy of the OracleCustomerDAO object.
public class OracleDAOFactory extends DAOFactory {
public CustomerDAO getCustomerDAO() {
return new OracleCustomerDAO();
}
...
}
The MSSQLDAOFactory has a similar method. Both implementations of the method return an object reference of the type CustomerDAO. This allows the business object, e.g., CustomerBean, to use the object to get customer data through the interface without caring which database the data is coming from.
The last thing we need to do is hide the Factory implementation from the business object. We can do this using a generic abstract class, DAOFactory. This class can implement the code to determine which data source to use and be the superclass for the OracleDAOFactory and the MSSQLDAOFactory. The code to determine which data source is in use is not shown but we could find out by reading in data from a Java properties file or an XML file, or looking it up in a JNDI Naming Service.
The abstract class, DAOFactory, can also define an abstract method, getDAOFactory, that's responsible for returning the correct factory object. It's the job of the subclass factory object to create the correct CustomerDAO for the given data source, as we saw earlier.
public abstract class DAOFactory {
// abstract getXXXDAO methods
public abstract CustomerDAO getCustomerDAO();
// getDAOFactory
public static DAOFactory getDAOFactory() {
String factoryClass = "":
// determine which factory class to use
...
Class _class = Class. forName (factoryClass);
Object _object = _class. newInstance();
if (_object instanceof DAOFactory) {
factoryInstance = (DAOFactory) _object;
}
else {
// throw Exception
}
// Need to handle the
// ClassNotFoundException
// InstantiationException
// IllegalAccessException
return factoryInstance;
}
}
Our business object CustomerBean can now use either an Oracle or a Microsoft database to get, add, update, or delete a customer. The following code shows how a business object might use these objects to delete a customer:
String customer_id = "100";
DAOFactory df = DAOFactory.getDAOFactory();
CustomerDAO cust = df.getCustomerDAO();
cust.deleteCustomer(customer_id);
In this example we're writing to a type instead of a specific implementation. The code doesn't depend on the database that's in use and the application can quickly be changed to use new databases, such as Sybase. A new CustomerDAO class will need to be implemented using the Sybase SQL syntax to access customer data, and a Sybase version of the DAOFactory will need to be written; however, all the business objects that use the customer data won't require any changes.
Wrapping It Up
We've looked at how to write code to a type rather than to an
implementation and saw how this can create a tremendous amount of
flexibility in our applications. This is because the type determines what
the object can do, and the implementation determines how the object does it.
The last thing to consider is how to determine when to use an abstract class and when to use an interface. Interfaces allow classes that don't share any implementation hierarchy (inheritance) to be grouped together and still share a type. However, when we use an interface, we don't get any implementation reuse as we do in the CustomerDAO interface.
When we use the abstract class as a supertype we get implementation reuse that doesn't need to be duplicated across multiple classes. For example, the DAOFactory can share the implementation code that determines which database to use. Using an abstract class, however, locks our class into an inheritance hierarchy and prevents other classes that already extend a particular class from sharing the type. It also prevents classes that extend the abstract class from being able to extend other classes.
This was not a major factor in the DAO pattern implementation but is usually a concern in other designs. A final consideration is that adding additional methods to the interface breaks all the classes that implement the interface, because each class is required to implement the new method, while adding methods to an abstract class can be done without affecting any subclasses.
References
Published September 1, 2002 Reads 15,683
Copyright © 2002 SYS-CON Media, Inc. — All Rights Reserved.
Syndicated stories and blog feeds, all rights reserved by the author.
More Stories By Mike Barlotta
Background Information: Michael Barlotta is the Director of Technology at AEGIS.net Inc (www.AEGIS.net). Mike is a Sun Certified Java Programmer and is recognized as an expert on the Sybase application server EAServer (Jaguar CTS), mentoring clients and speaking at conferences on the topic. He is the author of several books including Taming Jaguar and Jaguar Development with PowerBuilder 7 (both by Manning Publications). Be sure to check out Mike’s Web site www.TamingJaguar.com.
![]() |
Bret Hansen 09/06/02 01:19:00 PM EDT | |||
I would suggest that your DAOFactory look like this: public abstract class DAOFactory { This requires a super type (class or interface) of DAO. This allows for the addition of new DAOs without adding new methods to the Factory as well as not requiring a recompile of the Factory (If it is written correctly). An other benefit is it allows for different business objects to be stored in different data stores. Some in LDAP, some in a RDBMS, and some in a backend server. All configurable at runtime. This would change the use to this (one lese line, but now requires a cast): String customer_id = "100"; |
||||
- Three Tips to Successfully Load Test Adobe Flex Applications
- Patterns for Building High Performance Applications
- It's the Java vs. C++ Shootout Revisited!
- Asynchronous Logging Using Spring
- Graal, a Dynamic Java Compiler in the Works
- Cross-Platform Mobile Website Development – a Tool Comparison
- Write Once Run Anywhere or Cross Platform Mobile Development Tools
- Three Buzzwords That Every CIO Hears but One They Should Listen To
- Cloud Expo New York: The Java EE 7 Platform - Developing for the Cloud
- Immersing into JavaScript Frameworks
- Workday Reportedly Prepping to Go Public
- Book Review: Sams Teach Yourself Java in 24 Hours
- Three Tips to Successfully Load Test Adobe Flex Applications
- Book Excerpt: Introducing HTML5
- Five Years Waiting for JRE 7: Is It Justified? (Part 1)
- Book Excerpt: Java Application Profiling Tips and Tricks
- i-Technology in 2012: Five Industry Predictions
- Patterns for Building High Performance Applications
- It's the Java vs. C++ Shootout Revisited!
- OpenXava 4.3: Rapid Java Web Development
- The Next Web Architecture
- Asynchronous Logging Using Spring
- Java for Programmers (2nd Edition)
- Graal, a Dynamic Java Compiler in the Works
- A Cup of AJAX? Nay, Just Regular Java Please
- Java Developer's Journal Exclusive: 2006 "JDJ Editors' Choice" Awards
- JavaServer Faces (JSF) vs Struts
- The i-Technology Right Stuff
- Rich Internet Applications with Adobe Flex 2 and Java
- Java vs C++ "Shootout" Revisited
- Bean-Managed Persistence Using a Proxy List
- Reporting Made Easy with JasperReports and Hibernate
- Creating a Pet Store Application with JavaServer Faces, Spring, and Hibernate
- Why Do 'Cool Kids' Choose Ruby or PHP to Build Websites Instead of Java?
- What's New in Eclipse?
- i-Technology Predictions for 2007: Where's It All Headed?



















