Laboratory: Creating a Facade
CSC 207 Algorithms and Object Oriented Design Spring 2010

Summary: In this lab, you will construct a class using the facade pattern.

Background

In class, we discussed that the facade pattern is used when there are many classes or object with some great functionality, but which can be overly complex for the average or typical user. In these cases, we'd rather have a much simpler interface to make use of a small set of the functionality available to us. In addition, this decouples our client code from the complicated classes, since clients will only interface with the facade.

One place where this might be necessary is with Java's rich formatting tools, found in the java.text package. Using these, numbers and strings can be formatted in pretty much every way conceivable. As a result, the classes are long, with many many functions, and the documentation is correspondingly arduous to wade through.

It took the author of this lab about an hour to read, synthesize, implement, and test the functionality you will see below. While this may be acceptable for an advanced programmer (perhaps they will more frequently need to make use of the package's flexibility), it is an unacceptable use of time for, say, the casual programmer that simply needs to produce reports using a required style.

Let's say that an institution requires a particular format for some common outputs: dates, integers, monetary values, and people. The following is a monolithic function (which you should be growing to disdain), that uses the java.text package to put these values into the required formats. A few examples of the use of each are then shown.

SampleFormats.java
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.GregorianCalendar;
import java.text.DecimalFormat;
import java.text.MessageFormat;

public class SampleFormats {

  public static void main(String[] args) {

    /* Date format. Examples: 
       4 Jul 1997
       10 Mar 1979 */
    SimpleDateFormat dateFormat = new SimpleDateFormat("d MMM yyyy");
    
    /* A pretty integer format. Examples:
       4,235,682
       5,487 
       42
    */
    DecimalFormat intFormat = new DecimalFormat("#,###");

    /* A monetary format. Examples:
       $ 4,235,670
       $ 345.23
       $ 0.48
    */
    DecimalFormat dollarFormat = new DecimalFormat("$ #,##0.##");

    /* A person format using first, last, and user names. Examples:
       Weinman, Jerod [weinman]
       Davis, Janet [davisjan]
       Coahran, Marge [coahranm]

       The {x} syntax means replace with the x'th index of an array.
    */
    MessageFormat personFormat = new MessageFormat("{0}, {1} [{2}]");
    

    /* Tests */
    System.out.println("Date: " +  
                       dateFormat.format 
                       ( new GregorianCalendar(2005, 7,4).getTime()));
    // dateFormat.format() expects a Date object. Use
    // GregorianCalendar to construct a Calendar object and the
    // getTime() method to convert it to a Date.

    System.out.println("Integer: " +  intFormat.format(1234567) );
    System.out.println("Integer: " +  intFormat.format(67.7) );
    
    System.out.println("Money: " +  dollarFormat.format(9812345.678) );
    System.out.println("Money: " +  dollarFormat.format(9812345) );
    System.out.println("Money: " +  dollarFormat.format(.78) );

    System.out.println("Person: " + personFormat.format
                       ( new Object[]{"Weinman","Jerod","weinman"} ) );
    // We can create and initialize an Object array on the fly, as
    // shown above.
  }

}
In this exercise, you will aid all future formatters by alleviating them of the need to spend the time to understand how to construct the required format using Java.

Exercises

Exercise 1

  1. If you haven't already, read through the code for SampleFormats above to make sure you understand it.
  2. Compile and run it and see if it gives you the outputs you expect.

Exercise 2

As mentioned above, a facade pattern unites the complex options of several classes and presents them as one unified (and simpler) tool. Below is an outline of a class representing some organizational formatting requirements.
BasicFormat.java
import java.util.Date;

/** Specifies basic formatting for dates, integers, money, and people */
public class BasicFormat {

  public static String formatDate( Date date ) {
    // BODY
  }

  /** Formats a date
   * @param year Full integral value of the year, e.g. 1945, 2008
   * @param month Zero-based month index, e.g. 0 is January, 6 is July
   * @param day One-based day of the month
   */
  public static String formatDate( int year, int month, int day ) {
    // BODY
  }

  public static String formatLong ( long number ) {
    // BODY
  }

  public static String formatMoney ( double amount )  {
    // BODY
    }

  public static String formatPerson ( String firstName, String lastName, 
                                      String userName) {
    // BODY
  }

}
  1. Why do you think the methods are declared static?
  2. Where should you declare your formatters (i.e., the variables of type DecimalObject etc.)? As class variables? Inside the static methods? Which do you think is more efficient?

Exercise 3

  1. Fill in the bodies of the procedures in BasicFormat, using the examples from SampleFormats.
  2. Test your formatter using the following class. Does it produce the results you expect?
TestBasicFormat.java
public class TestBasicFormat {

  public static void main(String[] args) {

    System.out.println("Date: " + BasicFormat.date(2009, 0, 7) );
    System.out.println("Date: " + BasicFormat.date(1930, 4, 11) );

    System.out.println("Integer: " +  
                       BasicFormat.formatLong(1234567) );
    
    System.out.println("Money: " +  
                       BasicFormat.formatMoney(9812345.678) );

    System.out.println("Money: " +  
                       BasicFormat.formatMoney(9812345) );

    System.out.println("Money: " +  
                       BasicFormat.formatMoney(.78) );

    System.out.println("Person: " + 
                       BasicFormat.formatPerson("Jerod",
                                                "Weinman",
                                                "weinman") );
  }

}

Exercise 4

  1. Say the organization using your BasicFormat class wishes to change the format of its dates to include the day of the week in abbreviated form, as in Sat 10 Mar 1979. Would they need to change the client code, as in TestBasicFormat above? Why or why not?
  2. Update your BasicFormat and/or TestBasicFormat so that the date is rendered with the day, as described above.

    Hint: You will want to browse the documentation for the appropriate Java class while also gaining an appreciation for having a facade.

Jerod Weinman
Created: 7 January 2009