junhong

          Design Pattern with java (part two)

          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.
          1. 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.
          2. 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());
            }
            }
            .......
          3. 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.

          posted on 2006-04-10 23:23 junhong 閱讀(528) 評論(0)  編輯  收藏 所屬分類: java技術

          主站蜘蛛池模板: 南康市| 博湖县| 兴和县| 防城港市| 富平县| 宁安市| 阿拉善左旗| 句容市| 方城县| 将乐县| 英吉沙县| 桃园市| 乌拉特后旗| 深州市| 景泰县| 奉新县| 锡林浩特市| 汉沽区| 尚志市| 张家川| 疏附县| 康乐县| 四川省| 望江县| 富源县| 镇平县| 江油市| 武宁县| 任丘市| 浑源县| 平舆县| 井冈山市| 延安市| 土默特右旗| 定边县| 农安县| 原阳县| 鄂温| 静乐县| 麻阳| 黄山市|