Comments
Richard Davies wrote: The UK has a good crop of technology pioneers in cloud computing - for example ElasticHosts, FlexiScale, Flexiant, OnApp - and also some strong government initiatives such as G-Cloud. We will have to see whether this kind of technical leadership converts into swift mass-market adoption or not.
Cloud Expo on Google News


2008 West
DIAMOND SPONSOR:
Data Direct
SOA, WOA and Cloud Computing: The New Frontier for Data Services
PLATINUM SPONSORS:
Red Hat
The Opening of Virtualization
GOLD SPONSORS:
Appsense
User Environment Management – The Third Layer of the Desktop
Cordys
Cloud Computing for Business Agility
EMC
CMIS: A Multi-Vendor Proposal for a Service-Based Content Management Interoperability Standard
Freedom OSS
Practical SOA” Max Yankelevich
Intel
Architecting an Enterprise Service Router (ESR) – A Cost-Effective Way to Scale SOA Across the Enterprise
Sensedia
Return on Assests: Bringing Visibility to your SOA Strategy
Symantec
Managing Hybrid Endpoint Environments
VMWare
Game-Changing Technology for Enterprise Clouds and Applications
Click For 2008 West
Event Webcasts

2008 West
PLATINUM SPONSORS:
Appcelerator
Get ‘Rich’ Quick: Rapid Prototyping for RIA with ZERO Server Code
Keynote Systems
Designing for and Managing Performance in the New Frontier of Rich Internet Applications
GOLD SPONSORS:
ICEsoft
How Can AJAX Improve Homeland Security?
Isomorphic
Beyond Widgets: What a RIA Platform Should Offer
Oracle
REAs: Rich Enterprise Applications
Click For 2008 Event Webcasts
SYS-CON.TV
Top Links You Must Click On


Java Design
Java Design

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

  • Gosling, J., Joy, B., and Steele, G. (1996). The Java Language Specification. Addison-Wesley.
  • Flanagan, D. (2002). Java in a Nutshell. O'Reilly.
  • Alur, D., Crupi, J., and Malks, D. (2001). Core J2EE Patterns: Best Practices and Design Strategies. Prentice Hall PTR.
  • J2EE BluePrints: http://java.sun.com/blueprints/
  • (Image and code) "Reveal the magic behind subtype polymorphism": www.javaworld.com/javaworld/jw-04-2001/ jw-0413-polymorph.html
  • "A primordial interface?": www.javaworld.com/javaworld/jw-03-2001/ jw-0309-primordial.html
  • "Thanks type and gentle class": www.javaworld.com/javaworld/jw-01-2001/jw-0119-type.html
    About 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.

  • In order to post a comment you need to be registered and logged in.

    Register | Sign-in

    Reader Feedback: Page 1 of 1

    I would suggest that your DAOFactory look like this:

    public abstract class DAOFactory {
    public DAO getDAO( Class daoClass ) {
    DAO dao;
    // determine which DAO class to use
    String doaClassName = ...
    Class doaClass = Class.forName( doaClassName );
    Object object = doaClass.newInstance();
    if ( object instanceof DAO ) {
    dao = (DAO) object;
    }
    else {
    // throw Exception
    }
    return dao;
    }
    }

    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";
    CustomerDAO cust = (CustomerDAO) DAOFactory.getDAO( CustomerDAO.class );
    cust.deleteCustomer(customer_id);


    Your Feedback
    Bret Hansen wrote: I would suggest that your DAOFactory look like this: public abstract class DAOFactory { public DAO getDAO( Class daoClass ) { DAO dao; // determine which DAO class to use String doaClassName = ... Class doaClass = Class.forName( doaClassName ); Object object = doaClass.newInstance(); if ( object instanceof DAO ) { dao = (DAO) object; } else { // throw Exception } return dao; } } 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....
    Enterprise Open Source Magazine Latest Stories . . .
    Apache Deltacloud, the Red Hat-contributed ReSTful API that abstracts differences between clouds so services on any cloud can be managed – provided of course there’s a driver – has graduated from the Apache Foundation’s incubator and is now a full-fledged Top-Level Project (TLP). The...
    With Cloud Expo 2012 New York (10th Cloud Expo) just four months away, what better time to start introducing you in greater detail to the distinguished individuals in our incredible Speaker Faculty for the technical and strategy sessions at the conference... We have technical and st...
    AMD said late Tuesday that its chief sales officer Emilio Ghilardi had left the company and that CEO and president Rory Read is going to do his job while a replacement is sought. AMD didn’t say why Ghilardi left but it’s assumed Read wants his own people. Read is relatively new to th...
    During the lifespan of M3 (Monitis Monitor Manager) there has always been something lacking – timers. M3 execution procedure was outlined in this previous article. The execution mentioned in the latter was a one-time-execution, whereas server monitoring requires periodic invocati...
    Red Hat is putting its bought-in Gluster scale-out NAS storage technology, acquired in October, on the Amazon cloud. It’s styled Red Hat Virtual Storage Appliance for Amazon Web Services and other clouds are supposed to follow in short order.
    A new episode of the screencast series is now available at the OpenNebula YouTube Channel. This screencast demonstrates the new easily-customizable self-service portal for cloud consumers. Its aim is to offer a simplified access to shared infrastructure for non-IT end users. The scree...
    Subscribe to the World's Most Powerful Newsletters
    Subscribe to Our Rss Feeds & Get Your SYS-CON News Live!
    Click to Add our RSS Feeds to the Service of Your Choice:
    Google Reader or Homepage Add to My Yahoo! Subscribe with Bloglines Subscribe in NewsGator Online
    myFeedster Add to My AOL Subscribe in Rojo Add 'Hugg' to Newsburst from CNET News.com Kinja Digest View Additional SYS-CON Feeds
    Publish Your Article! Please send it to editorial(at)sys-con.com!

    Advertise on this site! Contact advertising(at)sys-con.com! 201 802-3021


    SYS-CON Featured Whitepapers
    ADS BY GOOGLE