junhong

          My Links

          Blog Stats

          News

          常用鏈接

          留言簿(2)

          隨筆分類

          隨筆檔案

          文章檔案

          相冊(cè)

          收藏夾

          common component

          搜索

          積分與排名

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

          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 閱讀(527) 評(píng)論(0)  編輯  收藏 所屬分類: java技術(shù)

          主站蜘蛛池模板: 博白县| 永清县| 四子王旗| 额济纳旗| 泾源县| 临高县| 岐山县| 延津县| 托里县| 漠河县| 河南省| 澄江县| 新乐市| 阿巴嘎旗| 廉江市| 兰州市| 会宁县| 贡山| 水城县| 东莞市| 灵宝市| 扎兰屯市| 冀州市| 曲靖市| 青田县| 海林市| 扎囊县| 新郑市| 广西| 汝州市| 五原县| 新竹市| 紫金县| 黎城县| 清流县| 合山市| 喀喇| 临漳县| 黑河市| 莱州市| 怀宁县|