2.4.  Design a class that uses the Factory design pattern

[Note]

The Factory Method design pattern is a way to encapsulate object creation. Without a Factory Method, you would simply call the class's constructor directly: Foo x = new Foo(). With this pattern, you would instead call the factory method: Foo x = Foo.create(). The constructors are marked private, so they cannot be called except from inside the class, and the Factory Method is marked as static so that it can be called without first having an object.

Consider the following interface:

public interface Logger {

    // Write out a debug message
    public void debug(String msg);

    // Write out an error message
    public void error(String msg);
}
					

Suppose that you have written two implementations. One implementation writes the messages out to the standard console, while another writes them to a file:

public class ConsoleLogger implements Logger {

    ConsoleLogger() {} // Not accessible from other packages !

    public void debug(String msg) {
        out.println("DEBUG: " + msg);
    }

    public void error( String msg) {
        out.println("ERROR: " + msg);
    }
}
					

public class FileLogger implements Logger {

    private PrintWriter pw;

    FileLogger() throws IOException { // Not accessible from other packages !
        // throws java.io.FileNotFoundException if the file does not exist
        pw = new PrintWriter(new FileWriter("/tmp/logger.log" ) );
    }

    public void debug(String msg) {
        pw.println("DEBUG: " + msg);
        pw.flush();
    }

    public void error(String msg) {
        pw.println("ERROR: " + msg);
        pw.flush();
    }
}
					

Using a Factory Method to obtain an instance can save you a lot of work later. If you use a Factory Method to obtain your instance, you need to make only one change in one class in order to meet the new requirements. You do not need to make changes in every class that uses Logger:

public class LoggerFactory {

    private static Logger l = null;

    public static Logger getLogger() {
        if (l == null) {
            try {
                l = new FileLogger(); // Can fail if log file does not exist
            } catch (IOException e) {
                l = new ConsoleLogger();
            }
        }
        return l;
    }
}
					

Client code will look like:

public class LoggerTest {
     public static void main(String[] args) {
         LoggerFactory.getLogger().debug("Test debug");
         LoggerFactory.getLogger().error("Test error");
    }
}
					

There are a few advantages to this pattern:

Today factories have largely been brushed aside in favor of using Dependency Injection (DI) because they require a lot of boiler-plate code that turns out to be a little hard to maintain itself. Dependency Injection is basically equivalent to factories but allows you to specify how your objects get wired together declaratively (through XML configuration or annotations).

Usage of factory Design Patterns in Java Se and Java EE

Abstract factory (recognizeable by creational methods returning an abstract/interface type):

Factory method (recognizeable by creational methods returning a concrete type)

Class NumberFormat

NumberFormat is the abstract base class for all number formats. This class provides the interface for formatting and parsing numbers. NumberFormat also provides methods for determining which locales have number formats, and what their names are.

NumberFormat helps you to format and parse numbers for any locale. Your code can be completely independent of the locale conventions for decimal points, thousands-separators, or even the particular decimal digits used, or whether the number format is even decimal.

To format a number for the current Locale, use one of the factory class methods:

NumberFormat nf	= NumberFormat.getInstance();
String myString = nf.format(myNumber);
					

To format a number for a different Locale, specify it in the call to getInstance(...):

NumberFormat nf = NumberFormat.getInstance(Locale.FRENCH);
					

The NumberFormat class has many factory methods:

public static final NumberFormat getInstance()
public static NumberFormat getInstance(Locale inLocale)

public static final NumberFormat getNumberInstance()
public static NumberFormat getNumberInstance(Locale inLocale)

public static final NumberFormat getIntegerInstance()
public static NumberFormat getIntegerInstance(Locale inLocale)

public static final NumberFormat getCurrencyInstance()
public static NumberFormat getCurrencyInstance(Locale inLocale)

public static final NumberFormat getPercentInstance()
public static NumberFormat getPercentInstance(Locale inLocale)
					

Professional hosting         Free 'Oracle Certified Expert Web Services Developer 6' Guide     Free SCDJWS 5.0 Guide