Try pseudo-persistence for mock ups

It's possible to build Data Access Objects which mimic persistance, but whose data lasts only until the application shuts down. One might call this "pseudo-persistance", and such objects "pseudo-DAOs".

These stub classes are easy to construct, and can be useful for quick mock ups. They usually require less effort than providing true persistance. By following the style shown below, for example, a pseudo-DAO could be constructed in 10 minutes.

This example pseudo-DAO implements pseudo-persistence for Person objects. The intent is to create a pseudo-DAO whose methods will match the final, true DAO. Thus, the same class can evolve from a mock up into a final implementation, without affecting the caller in any way. From the caller's point of view, there should be little or no difference between the pseudo-DAO and the real DAO, including the checked exceptions thrown by its methods.

The underlying technique is simply to store objects in a static member of the pseudo-DAO. In this case, a Map is used.


package myapp.data;

import java.util.*;

import myapp.business.Person;

/**
* Provides "pseudo-persistance", by storing objects as static data attached to this
* class. Such data is lost when the application is shut down, but is retained
* as long as the application is running.
*
* <P>The important thing is to match the desired style of the true DAO 
* into which this pseudo-DAO may evolve.
*
* <P>Note that <tt>DataAccessException</tt> (a checked exception) can and should
* be declared in the throws clause, even when the underlying implementation for
* this pseudo-DAO never throws such an exception. Again, the idea is to provide
* a stub which, from the point of view of the caller, is as realistic as possible.
*/
public final class PersonDAO {

  /**
  * Add <tt>aPerson</tt> to the datastore, returning an indicator of
  * success or failure.
  *
  * If <tt>aPerson</tt> already exists in the datastore, then return false.
  */
  public boolean add(Person aPerson) throws DataAccessException {
    boolean result = false;
    synchronized(fPersons) {
      if (! fPersons.containsKey(aPerson.getName())) {
        fPersons.put(aPerson.getName(), aPerson);
        result = true;
        log("Persons after add: " + fPersons);
      }
    }
    return result;
  }

  /**
  * Fetch a person from the datastore, using <tt>aName</tt> as a unique
  * identifier.
  *
  * <P>If no <tt>Person</tt> is found, return null.
  */
  public Person fetch(String aName) throws DataAccessException {
    Person result = null;
    synchronized(fPersons){
      if(fPersons.containsKey(aName)){
        result = fPersons.get(aName);
      }
      log("Persons during fetch: " + fPersons);
    }
    return result;
  }

  /**
  * Update the data associated with <tt>aPersons</tt>, returning an
  * indicator of success or failure.
  *
  * <P>If <tt>aPerson</tt> is not found in the datastore, then return false.
  */
  public boolean change(Person aPerson) throws DataAccessException {
    boolean result = false;
    synchronized(fPersons){
      if (fPersons.containsKey(aPerson.getName())) {
        fPersons.put(aPerson.getName(), aPerson); //replaces old entry
        result = true;
        log("Persons after change: " + fPersons);
      }
    }
    return result;
  }

  /**
  * Delete the <tt>Person</tt> identified uniquely by <tt>aName</tt>,
  * returning an indicator of success or failure.
  *
  * <P>If <tt>aName</tt> is not found in the datastore, then return false.
  */
  public boolean delete(String aName) throws DataAccessException {
    boolean result = false;
    synchronized(fPersons){
      if (fPersons.containsKey(aName)) {
        fPersons.remove(aName);
        result = true;
        log("Persons after delete: " + fPersons);
      }
    }
    return result;
  }

  // PRIVATE 

  /**
  * Stores Person objects in a static field, attached to this class, which will
  * remain available as long as this class remains loaded.
  */
  private static Map<String, Person> fPersons = new LinkedHashMap<>();

  private void log(String aText){
    System.out.println(aText);
  }
} 



See Also :
Data access objects
Would you use this technique?
Yes   No   Undecided   
© 2014 Hirondelle Systems | Source Code | Contact | License | RSS
Individual code snippets can be used under this BSD license - Last updated on September 21, 2013.
Over 2,000,000 unique IPs last year - Built with WEB4J.
- In Memoriam : Bill Dirani -