Encapsulating creation
		
		
				
						
				
		
		
				Although only the Simple Factory Method is a true singleton, you’ll find that each specify 
		
		
				factory class in the more general types of factories will only have a single instance.
				
		
		
				- Simple Factory method
 One approach is to make the factory a static method of the base class:
 //: factory:shapefact1:ShapeFactory1.java
 // A simple static factory method.
 package factory.shapefact1;
 import java.util.*;
 import junit.framework.*;
 abstract class Shape {
 public abstract void draw();
 public abstract void erase();
 public static Shape factory(String type) {
 if(type.equals("Circle")) return new Circle();
 if(type.equals("Square")) return new Square();
 throw new RuntimeException(
 "Bad shape creation: " + type);
 }
 }
 class Circle extends Shape {Circle() {} // Package-access constructor
 public void draw() {
 System.out.println("Circle.draw");
 }
 public void erase() {
 System.out.println("Circle.erase");
 }
 }
 class Square extends Shape {
 Square() {} // Package-access constructor
 public void draw() {
 System.out.println("Square.draw");
 }
 public void erase() {
 System.out.println("Square.erase");
 }
 }
 public class ShapeFactory1 extends TestCase {
 String shlist[] = { "Circle", "Square",
 "Square", "Circle", "Circle", "Square" };
 List shapes = new ArrayList();
 public void test() {
 Iterator it = Arrays.asList(shlist).iterator();
 while(it.hasNext())
 shapes.add(Shape.factory((String)it.next()));
 it = shapes.iterator();
 while(it.hasNext()) {
 Shape s = (Shape)it.next();
 s.draw();
 s.erase();
 }
 }
 public static void main(String args[]) {
 junit.textui.TestRunner.run(ShapeFactory1.class);
 }
 } ///:~
 To encourage creation to only happen in the factory( ), the constructors for the specific
 types of Shape are give package access, so factory( ) has access to the constructors but they
 are not available outside the package.
- Polymorphic factories
 different types of factories can be subclassed from the basic factory,for example
 interface Shape {
 void draw();
 void erase();
 }
 abstract class ShapeFactory {
 protected abstract Shape create();
 private static Map factories = new HashMap();
 public static void
 addFactory(String id, ShapeFactory f) {
 factories.put(id, f);
 }
 // A Template Method:
 public static final
 Shape createShape(String id) {
 if(!factories.containsKey(id)) {
 try {
 // Load dynamically
 Class.forName("factory.shapefact2." + id);
 } catch(ClassNotFoundException e) {
 throw new RuntimeException(
 "Bad shape creation: " + id);
 }
 // See if it was put in:
 if(!factories.containsKey(id))
 throw new RuntimeException(
 "Bad shape creation: " + id);
 }
 return
 ((ShapeFactory)factories.get(id)).create();
 }
 }
 class Circle implements Shape {
 private Circle() {}
 public void draw() {
 System.out.println("Circle.draw");
 }
 public void erase() {
 System.out.println("Circle.erase");
 }
 private static class Factory
 extends ShapeFactory {
 protected Shape create() {
 return new Circle();
 }
 }
 static {
 ShapeFactory.addFactory(
 "Circle", new Factory());
 }
 }
 .......
- Abstract factories
 The Abstract Factory pattern looks like the factory objects we’ve seen previously, with not
 one but several factory methods. Each of the factory methods creates a different kind of
 object. The idea is that at the point of creation of the factory object, you decide how all the
 objects created by that factory will be used.
 As another example suppose you are creating a general-purpose gaming environment and you
 want to be able to support different types of games
 interface Obstacle {
 void action();
 }
 interface Player {
 void interactWith(Obstacle o);
 }
 class Kitty implements Player {
 public void interactWith(Obstacle ob) {
 System.out.print("Kitty has encountered a ");
 ob.action();
 }
 }
 class KungFuGuy implements Player {
 public void interactWith(Obstacle ob) {
 System.out.print("KungFuGuy now battles a ");
 ob.action();
 }
 }
 class Puzzle implements Obstacle {
 public void action() {
 System.out.println("Puzzle");
 }
 }
 class NastyWeapon implements Obstacle {
 public void action() {
 System.out.println("NastyWeapon");
 }
 }
 // The Abstract Factory:
 interface GameElementFactory {Player makePlayer();
 Obstacle makeObstacle();
 }
 // Concrete factories:
 class KittiesAndPuzzles
 implements GameElementFactory {
 public Player makePlayer() {
 return new Kitty();
 }
 public Obstacle makeObstacle() {
 return new Puzzle();
 }
 }
 class KillAndDismember
 implements GameElementFactory {
 public Player makePlayer() {
 return new KungFuGuy();
 }
 public Obstacle makeObstacle() {
 return new NastyWeapon();
 }
 }
 class GameEnvironment {
 private GameElementFactory gef;
 private Player p;
 private Obstacle ob;
 public GameEnvironment(
 GameElementFactory factory) {
 gef = factory;
 p = factory.makePlayer();
 ob = factory.makeObstacle();
 }
 public void play() { p.interactWith(ob); }
 }
 public class Games extends TestCase {
 GameElementFactory
 kp = new KittiesAndPuzzles(),
 kd = new KillAndDismember();
 GameEnvironment
 g1 = new GameEnvironment(kp),
 g2 = new GameEnvironment(kd);
 // These just ensure no exceptions are thrown:
 public void test1() { g1.play(); }
 public void test2() { g2.play(); }
 public static void main(String args[]) {
 junit.textui.TestRunner.run(Games.class);
 }
 } ///:~
 In this environment, Player objects interact with Obstacle objects, but there are different
 types of players and obstacles depending on what kind of game you’re playing. You determine
 the kind of game by choosing a particular GameElementFactory, and then the
 GameEnvironment controls the setup and play of the game. In this example, the setup and
 play is very simple, but those activities (the initial conditions and the state change) can
 determine much of the game’s outcome. Here, GameEnvironment is not designed to be
 inherited, although it could very possibly make sense to do that.