import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; public enum FRUIT_TYPE { NONE, APPLE, BANANA, } class Program { /** * @param args */ public static void main(String[] args) { Fruit.getFruitByTypeName(FRUIT_TYPE.BANANA); Fruit.showAll(); Fruit.getFruitByTypeName(FRUIT_TYPE.APPLE); Fruit.showAll(); Fruit.getFruitByTypeName(FRUIT_TYPE.BANANA); Fruit.showAll(); } } public class Fruit { private static Map types = new HashMap(); /** * Using a private constructor to force the use of the factory method. * @param type */ private Fruit(FRUIT_TYPE type) { } /** * Lazy Factory method, gets the Fruit instance associated with a certain * type. Instantiates new ones as needed. * @param type Any allowed fruit type, e.g. APPLE * @return The Fruit instance associated with that type. */ public static Fruit getFruitByTypeName(FRUIT_TYPE type) { Fruit fruit; if (!types.containsKey(type)) { // Lazy initialisation fruit = new Fruit(type); types.put(type, fruit); } else { // OK, it's available currently fruit = types.get(type); } return fruit; } /** * Lazy Factory method, gets the Fruit instance associated with a certain * type. Instantiates new ones as needed. Uses double-checked locking * pattern for using in highly concurrent environments. * @param type Any allowed fruit type, e.g. APPLE * @return The Fruit instance associated with that type. */ public static Fruit getFruitByTypeNameHighConcurrentVersion(FRUIT_TYPE type) { // This has concurrency issues. Here the read to types is not synchronized, // so types.put and types.containsKey might be called at the same time. // Don't be surprised if the data is corrupted. if (!types.containsKey(type)) { synchronized (types) { // Check again, after having acquired the lock to make sure // the instance was not created meanwhile by another thread if (!types.containsKey(type)) { // Lazy initialisation types.put(type, new Fruit(type)); } } } return types.get(type); } /** * Displays all entered fruits. */ public static void showAll() { if (types.size() > 0) { System.out.println("Number of instances made = " + types.size()); for (Entry entry : types.entrySet()) { System.out.println( Constants.firstLetterToUpper(entry.getKey().toString())); } System.out.println(); } } } ---- CategoryCoding