Java-Gaming.org    
Featured games (79)
games approved by the League of Dukes
Games in Showcase (477)
Games in Android Showcase (107)
games submitted by our members
Games in WIP (536)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: 1 [2]
  ignore  |  Print  
  Singletons  (Read 4852 times)
0 Members and 1 Guest are viewing this topic.
Offline ReBirth
« Reply #30 - Posted 2012-01-29 04:36:35 »

So you mean the Factory is not singleton, but holding static variable of sprites right?

Offline UprightPath
« Reply #31 - Posted 2012-01-29 05:24:34 »

This is where the terminology gets a little lacking, and ends up rather depending on how you decide to implement it.

The Factory doesn't have to be a Singleton, it can be, but it doesn't have to be. Especially if you're providing different graphic modes (Think having multiple themes, or having different art sets). Instead, you'd have several Factories that are handed around to contain the different graphic modes.

Let me explain Flyweight in better detail first.

1) FlyweightFactory- This class holds the instances to the Flyweight objects, and typically has a method of getting a specific Flyweight Object.
2) FlyweightInterface<Interface/Abstract/ExtendableClass>- Defines the operations that a Flyweight has to provide. In the case of using them for graphics, this would be something like "drawAt(int x, int y)" or "drawFrameAt(int x, int y, int frameId)". Basically handling all of the different methods for drawing a specific thing.
3) ConcreteFlyweight- Implements/Extends the FlyweightInterface and provides the specifics of drawing the sprite where you want it. This allows you to remove the act of drawing from the Client (see next point).
4) FlyweightClient- An object of some type that knows about the Factory and uses a FlyweightInterface (ConcreteFlyweight). This can be an Entity in your game, or something else. It's what handles the 'logic' of whatever the object is.

Your ConcreteFlyweight would either directly hold an instance of your sprites, or would point to something that does. Since everything has to go through the FlyweightFactory to get to the Sprites (And since the FlyweightFactory ensures that there's only one instance of each ConcreteFlyweight available through it) then you're keeping your sprite memory usage to a minimum.

Offline ReBirth
« Reply #32 - Posted 2012-01-30 00:35:00 »

Well with above way you can avoid singleton. Just pass factory instance to each entity and make sure you construct the factory once in one class.

Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline UprightPath
« Reply #33 - Posted 2012-01-30 03:12:41 »

Yep, that's exactly the point.

If you're only going to have one graphic type, or think you're going to need one Factory, you can make it a static class instead and have it act like a Singleton.

Offline ReBirth
« Reply #34 - Posted 2012-01-30 03:15:54 »

What I do now is just passing static instance of factory class.

Offline UprightPath
« Reply #35 - Posted 2012-01-30 03:48:25 »

That should be perfectly fine. Really, the only time you should worry about doing it another way is if you foresee some point in the future that your current code base will need to use multiple factories.

Either way, it's good practice using another type of Design Pattern that a lot of people end up avoiding it seems.

Offline sproingie

JGO Kernel


Medals: 202



« Reply #36 - Posted 2012-01-30 17:59:07 »

Passing around the factory is the way to do it.  You shouldn't need to pass it around all that much, because inner classes can stand in for finer-grained factories.  If you're passing around the factory, you may as well make that an instance, if for no other reason than to cut down on the Class<Foo>/Foo.class noise you have to bother with when passing around classes.

Offline ReBirth
« Reply #37 - Posted 2012-01-31 13:08:22 »

If you're passing around the factory, you may as well make that an instance, if for no other reason than to cut down on the Class<Foo>/Foo.class noise you have to bother with when passing around classes.
I don't understand Huh

Offline sproingie

JGO Kernel


Medals: 202



« Reply #38 - Posted 2012-01-31 18:02:47 »

If you use a static factory, like FooFactory, then the only way to pass it around between objects is to use "FooFactory.class", and the only safe way to declare it is with Class<FooFactory>.  This is noisy and annoying, when you could instead just do "fac =  new FooFactory()" then pass it in like any other object.  Also, you can make FooFactory take args, like a configuration.

Offline UprightPath
« Reply #39 - Posted 2012-01-31 21:38:36 »

I think what Sproingie meant is that while you could just write in FooFactory.getFlyweight(id) everywhere you're going to need to, that it's not always a good thing to do so. Passing it like a parameter would be better, but as he said it would require the clunkiness of the Class class (Har har) to do so if all of the access is through static methods.

What I think Sproingie meant.
1  
2  
3  
4  
5  
6  
public class StaticTester {

    public static void doOp() {
        System.out.println("Op is did.");
    }
}

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
public class StaticExample {

    StaticTester staticObject;

    public StaticExample(StaticTester staticObject) {
        this.staticObject = staticObject;
    }

    private StaticExample(Class<StaticTester> aClass) throws InstantiationException, IllegalAccessException {
        this.staticObject = aClass.newInstance();
    }

    public void doOp() {
        System.out.println("Example did.");
        staticObject.doOp();
        System.out.println("Example did again.");
    }

    public static void main(String[] args) throws InstantiationException, IllegalAccessException {
        StaticExample se = new StaticExample(StaticTester.class);
        se.doOp();
    }
}


Using static methods also adds in the problem of how the static fields are initialized...
Do you have to call FooFactory.initialize() first? Which would mean that you would have to call FooFactory.initialize() prior to it being used anywhere and probably put in checks for many of the functions you'd use with it to ensure that it was initialized.
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
public class StaticTester {
    private static boolean isInit = false;
    private static String say;
   
    public static void initialize() {
        say = "We say this.";
        isInit = true;
    }
   
    public static void doOp() {
        if(isInit) {
            System.out.println(say);
        } else {
            throw new ClassNotInitializedException("This is made up!");
        }
    }
}

Do you use a static initialization block in the FooFactory code? However, this takes away a lot of your ability to decide when/where/how the information gets initialized as it is called when the class is first imported or used (Not completely certain there, but you don't have control).
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
public class StaticTester {

    private static String say;

    static {
        say = "We say this.";
    }

    public static void doOp() {
        System.out.println(say);
    }
}


Having another class create it, or make the first call to some static method in FooFactory to get an instance of FooFactory, then passing it to each object takes care of those issues. It also makes replacing the factory easier (Going from static calls like FooFactory.method() to object.method() can be fun.)
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
public class StaticExample {

    StaticTester staticObject;

    public StaticExample(StaticTester staticObject) {
        this.staticObject = staticObject;
    }

    public void doOp() {
        System.out.println("Example did.");
        System.out.println(staticObject.getInitializationVariable());
        System.out.println("Example did again.");
    }

    public static void main(String[] args) {
        StaticTester.createInstance("New stringer string!");
        StaticExample se = new StaticExample(StaticTester.getInstance());
        se.doOp();
    }
}

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
public class StaticTester {

    private static StaticTester instance;
   
    public static void createInstance(String initializationVariable) {
        instance = new StaticTester(initializationVariable);
    }
   
    public static StaticTester getInstance() {
        if(instance == null) {
            throw new ClassNotInitializedException("This is made up!");
        } else {
            return instance;
        }
    }
   
    private String initializationVariable;
   
    private StaticTester(String initializationVariable) {
        this.initializationVariable = initializationVariable;
    }
   
    public String getInitializationVariable() {
        return initializationVariable;
    }
}


PS-- If someone can tell me how to get Spoilers and Code to work together I'll edit this. Also, if it'd be better to put all of these code snippets elsewhere do say so!

Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline sproingie

JGO Kernel


Medals: 202



« Reply #40 - Posted 2012-01-31 23:01:43 »

What I meant doesn't actually contain the word "static" anywhere in the code.  You just make your factory an object, use instance methods, and by all means allow for more than one factory.  If you store an instance somewhere on an existing "natural singleton", such as your "App" object, then it's already a de facto singleton, and it turns out that that's pretty much all you need.
Offline UprightPath
« Reply #41 - Posted 2012-01-31 23:10:48 »

Ah, I wasn't sure about the Class<FooFactory> portion of what you said. It's just something I've never run into.

Offline ReBirth
« Reply #42 - Posted 2012-02-01 01:06:40 »

if I try to to summary this,

1. make sure you only type once "new Factory()" in your project
2. pass the instance around to every states and entities

Offline SwampChicken
« Reply #43 - Posted 2012-02-01 05:28:32 »

I think a few of you would benefit greatly from having a browse through Effective Java (2nd Edition) by Joshua Bloch.
Offline sproingie

JGO Kernel


Medals: 202



« Reply #44 - Posted 2012-02-01 06:11:01 »

1. make sure you only type once "new Factory()" in your project

Right.  Chances are you'll want to stick it on a field somewhere.  When I'm using spring, I call it "context".  My scala apps using the cake pattern call it "module". 

2. pass the instance around to every states and entities

You pass it where it's needed, usually just for other singletons that need to create other instances they depend on via the factory.  At low levels where you're creating instances that are private to lower levels of your system, you can simply use inner classes.  You'd only need to use the factory if you need to customize it independently through the factory.  Your fine-grained classes like game entities, sprites, and so forth should not be aware of your factory.
Pages: 1 [2]
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

CogWheelz (15 views)
2014-07-30 21:08:39

Riven (22 views)
2014-07-29 18:09:19

Riven (14 views)
2014-07-29 18:08:52

Dwinin (12 views)
2014-07-29 10:59:34

E.R. Fleming (32 views)
2014-07-29 03:07:13

E.R. Fleming (12 views)
2014-07-29 03:06:25

pw (42 views)
2014-07-24 01:59:36

Riven (42 views)
2014-07-23 21:16:32

Riven (30 views)
2014-07-23 21:07:15

Riven (31 views)
2014-07-23 20:56:16
HotSpot Options
by dleskov
2014-07-08 03:59:08

Java and Game Development Tutorials
by SwordsMiner
2014-06-14 00:58:24

Java and Game Development Tutorials
by SwordsMiner
2014-06-14 00:47:22

How do I start Java Game Development?
by ra4king
2014-05-17 11:13:37

HotSpot Options
by Roquen
2014-05-15 09:59:54

HotSpot Options
by Roquen
2014-05-06 15:03:10

Escape Analysis
by Roquen
2014-04-29 22:16:43

Experimental Toys
by Roquen
2014-04-28 13:24:22
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!