Laboratory: Creating a Façade
CSC 207 Algorithms and Object Oriented Design Spring 2011

Summary: In this lab, you will construct a class using the façade pattern.

Background

In class, we discussed that the façade pattern is used when there are many classes or objects with some powerful and useful 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 a limited amount of functionality available. In addition, this decouples our client code from the complicated classes, because clients will only interface with the façade.

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 wading through documentation is correspondingly arduous.

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 she 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;


/**
 * A collection of sample usages for Java's string and number
 * formatting classes.
 *
 * @author Jerod Weinman
 */
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 façade pattern unites the complex options of several classes and presents them as one unified (and simpler) tool. You will create a façade for the complicated built-in Java formatting classes such as DecimalFormat, SimpleDateFormat, and MessageFormat).. That is, your implementation will use these classes behind the scenes, relieving a client programmer from having to figure out the correct format control strings.

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.
 *
 * @author YOUR NAME HERE
*/
public class BasicFormat {

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

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

  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
   * @return A date string in the form "DD MMM YYYY"
   */
  public static String formatDate( int year, int month, int day ) {
    // 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 DecimalFormat etc.)? As class variables? Inside the static methods? Which do you think is more efficient?

Exercise 3

  1. Add complete Javadoc documentation to the methods in BasicFormat. (Hint: use the comments in SampleFormats as a starting point.)
  2. Fill in the bodies of the methods in BasicFormat, using the example formats from SampleFormats.
  3. Test your formatter using the following class. Does it produce the results you expect?
TestBasicFormat.java
/**
 * Example uses of the basic formatting facade. 
 *
 * @author Jerod Weinman
 * @author YOUR NAME HERE 
 */
public class TestBasicFormat {

  public static void main(String[] args) {

    System.out.println("Date: " + BasicFormat.formatDate(2009, 0, 7) );
    System.out.println("Date: " + BasicFormat.formatDate(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 façade.

  3. Update the documentation of appropriately.

For those with extra time

Try your hand at building a flyweight.
Created: Jerod Weinman, 7 January 2009
Modified: Jerod Weinman, 17 January 2011
Modified: Jerod Weinman, 21 February 2011
Copyright © 2009-2011 Jerod Weinman.
CC-BY-NC-SA
This work is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 United States License .