Using the Singleton Pattern
Pages: 1, 2
Using the StringManager Class
The following example demonstrates how to use StringManager
from an application to support localized error messages in English and German.
The application takes two numbers from the user and shows the result of
addition of the numbers. The commands and result are displayed in either
English (the default) or German. The application consists of two packages:
myPackage1 and myPackage2. Listings 3 and 4 show the
LocalStrings.properties and
LocalStrings_de.properties files in myPackage1.
Listing 3. The LocalStrings.properties file in
myPackage1
promptInput=Please enter 2 numbers which are smaller than 100.
firstNumberRequest=Enter the First Number.
secondNumberRequest=Enter the Second Number.
invalidInput=Please type in a number.
result=Result
Listing 4. The LocalStrings_de.properties file in
myPackage1
promptInput=Tragen Sie bitte 2 Zahlen die sind kleiner als 100 ein.
firstNumberRequest=Tragen Sie die Erste Zahl ein.
secondNumberRequest=Tragen Sie die Zweite Zahl ein.
invalidInput=Bitte tippen eine Zahl ein.
result=Ergebnis
The LocalStrings.properties and
LocalString_de.properties in myPackage2 are given in
Listings 5 and 6, respectively.
Listing 5. The LocalStrings.properties file in myPackage2
smallNumbersOnlyWarning=One of the numbers is more than 100
Listing 6. The LocalStrings_de.properties file in
myPackage2
smallNumbersOnlyWarning=Eine der Zahlen ist mehr als 100.
The main class in this application is myPackage1.Test1, given
in Listing 7.
Listing 7. The myPackage1.Test1 class
package myPackage1;
import java.io.*;
import org.apache.catalina.util.StringManager;
import myPackage2.Adder;
public class Test1 {
int a, b;
protected static StringManager sm =
StringManager.getManager("myPackage1");
public void getInput() {
System.out.println(sm.getString("promptInput"));
InputReader inputReader = new InputReader();
a = inputReader.getFirstNumber();
b = inputReader.getSecondNumber();
}
private int add() {
Adder adder = new Adder();
return adder.addSmallNumbers(a, b);
}
public void printResult() {
System.out.println(sm.getString("result") + " : " + add());
}
public static void main(String[] args) {
Test1 test = new Test1();
test.getInput();
test.printResult();
}
}
First note the sm variable reference that gets an instance of
StringManager:
protected static StringManager sm =
StringManager.getManager("myPackage1");
The main method instantiates the class and calls the
getInput method and the printResult method. The
getInput method instantiates the InputReader class in
myPackage1 and calls its getFirstNumber and
getSecondNumber methods. The InputReader class in
listed in Listing 8.
Listing 8. The myPackage1.InputReader class
package myPackage1;
import java.io.*;
import org.apache.catalina.util.StringManager;
public class InputReader {
protected static StringManager sm =
StringManager.getManager("myPackage1");
public int getFirstNumber() {
int input = 0;
boolean inputValid = false;
while (!inputValid) {
System.out.println(sm.getString("firstNumberRequest"));
try {
BufferedReader userInput = new BufferedReader(new
InputStreamReader(System.in));
input = Integer.parseInt(userInput.readLine());
inputValid = true;
}
catch (Exception e) {
System.out.println(sm.getString("invalidInput"));
}
}
return input;
}
public int getSecondNumber() {
int input = 0;
boolean inputValid = false;
while (!inputValid) {
System.out.println(sm.getString("secondNumberRequest"));
try {
BufferedReader userInput = new BufferedReader(new
InputStreamReader(System.in));
input = Integer.parseInt(userInput.readLine());
inputValid = true;
}
catch (Exception e) {
System.out.println(sm.getString("invalidInput"));
}
}
return input;
}
}
The InputReader class also has a variable reference to an
instance of StringManager. Both the getFirstNumber and
getSecondNumber methods use the following code to obtain user
input:
BufferedReader userInput = new BufferedReader(new
InputStreamReader(System.in));
input = Integer.parseInt(userInput.readLine());
In the getFirstNumber method, the following line of code is
used to prompt the user to enter the first number:
System.out.println(sm.getString("firstNumberRequest"));
If the user entered an invalid input, the following line prints an error message:
System.out.println(sm.getString("invalidInput"));
The printResult method in the Test1 class
instantiates the Adder class in myPackage2 and calls
its addSmallNumbers method. The Adder class is given
in Listing 9.
Listing 9. The myPackage2.Adder class
package myPackage2;
import org.apache.catalina.util.StringManager;
public class Adder {
protected static StringManager sm =
StringManager.getManager("myPackage2");
public int addSmallNumbers(int a, int b) {
if (a>100 || b>100) {
// print warning
System.out.println(sm.getString("smallNumbersOnlyWarning"));
}
return a + b;
}
}
Again, this class has the reference to an instance of
StringManager.
protected static StringManager sm =
StringManager.getManager("myPackage2");
This time however, the getManager method gets
myPackage2 as the argument; therefore, a different instance of
StringManager is used than the one in the
myPackage1.Test1 and myPackage.InputReader classes.
The addSmallNumber method will print a warning if one of the two
arguments passed into it is greater than 100:
System.out.println(sm.getString("smallNumbersOnlyWarning"));
Now, run the myPackage1.Test1 class. If your computer's
language setting is English or a language other than German, here is what you
should see on the console after entering one number, one non-number, and
another number:
Please enter 2 numbers which are smaller than 100.Enter the
First Number.120
Enter the Second Number.3r
Please type in a number.Enter the Second Number.3
One of the numbers is more than 100Result : 123
If your computer setting uses German as its language, here is the result:
Tragen Sie bitte 2 Zahlen die sind kleiner als 100 ein.Tragen
Sie die Erste Zahl ein.120
Tragen Sie die Zweite Zahl ein.3r
Bitte tippen eine Zahl ein.Tragen Sie die Zweite Zahl ein.3
Eine der Zahlen ist mehr als 100.Ergebnis : 21123
Summary
The Singleton pattern is used to limit an instance of a class to one by
creating a private or protected constructor. You have learned a simple example
of the Singleton pattern in the SingletonFrame class. In other
uses, you can also use the Singleton pattern to restrict the number of
instances of a class to n. In this case, you need a way to maintain
the instances. A real-world example given is the StringManager
class in Tomcat. You have also seen how to use this class from your
application.
Budi Kurniawan is a senior J2EE architect and author.
Return to ONJava.com.