Singleton better than static? - java

So I have a player class in my game. Logically there only needs to be one player object (single player) But a lot of different classes need access to the player object. (ie, maps needs to know were player is, as does camera and enemies need to interact with the player, etc).
I have a couple of options.
Either I could pass this player object around to everything that needs it which is cumbersome. (Dependency injection I think it's called)
Just make it public static.
Make it a singleton.
What are the pros/cons of each?

I would not use a Singleton or static variable here and instead would hand a Player instance to the classes that need it via setters. If you only need one player instance - only call new Player() once :-)
See my take on Singletons here. Short summary: their typical misuse (avoiding "cumbersome" setters) violates OO and lowers design quality.
Static variables are cut from the same cloth as Singletons, along with the Monostate (non-static getters, static data, constructor is the "factory"). Avoid them. Consider if you made everything static: player, map, camera, enemies, etc. You would avoid a lot of "cumbersome" setters. But is it OO? When you finish your game can you reuse your pathfinding algorithms, AI algorithms, etc. on another game, or do they have too many global variables (Singletons et al) specific to your current game burned into them forever?

So, your options are:
Just make it public static.
Make it a singleton.
Both would effectively turn it into a global variable. I'm not a big fan of globals: they make everything harder to test and debug.
Pros: Easier access
Cons: Very high coupling (what if you want to make it a two player game?); Adds complexity to tests; Changing the player in one place might have unexpected consequences on other places.
I could pass this player object around to everything that needs it which is cumbersome. (Dependency injection I think it's called)
Pros: Lower coupling; Facilitates testing; You can pass copies of the player to other classes and reduce the chances of side-effects.
Cons: Having to pass Player references makes the API a bit more complex, but part of it may be mitigated by using a dependency injection framework, such as Guice.

Apart from teh advantages provided by Java Setter and Getter, I can't really think of any new ones that a singleton pattern (public static Type getInstance()) would give you over public variable (public static Type var).
But in general it's always better (from future pov) to control access to member variables (especially access from outside the class that has this as member variable), so I would recommend a private static variable with a public getter. Which is somewhere between a singleton and a public static var.

Using a singleton gives you the possibility to extend the base class and provide alternative implementations of Player, using a static method does now allow that flexibility.
Another point is that "conceptually" a player is an object and not a class.

I would avoid making it static. You want your code to be reusable and a player is certainly an object that may require several instances in an alternate project.
I would create simple getAttribute(), editAttribute methods that return or edit the attribute I need.
Another option would be to simply make the shareable attributes public within the player class although I would prefer the get/edit methods option.

Singletons can implement interfaces which can be used to refere to the singleton. i.e. you don't need hardcoded references to a singleton throughout your code. This makes unit testing easier, if you want a different instance for testing purposes.
public interface Printer {
public void print(String line);
}
public enum ConsolePrinter implements Printer {
INSTANCE;
public void print(String line) {
System.out.println(line);
}
}
// to print to the screen
Printer printer = ConsolePrinter.INSTANCE;
// for testing purposes.
Printer printer = createMock(Printer.class);

Related

create 1 static object or a class with static methods

I have a GUI class and the Logic class,
which is the better choice:
make the logic class methods static and access them LogicClass.method() from the gui class.
make the logic class regular and make 1 static object from this logic class
private static LogicClass logic;
make it non-static which is a little of a problem because i want to access some methods from the Main function in the GuiClass so it has to be static(i can access them through the constructor but I don't know if that's ok, something like connecting the server).
Static things are best avoided, because sooner or later, you'll want to separate different things, or have more than one instance of something, and then you'll be faced with a horrible refactoring.
It's like salt and water. It's easy to mix the two, but much more difficult to take them apart.
I would suggest you make all your stuff non-static. Just use the "new" and you'll be good to go. You might have to pass around some additional parameters, or introduce some additional fields, but it'll make your code much better in the long run. Only when you know in advance that you'll never have more than one instance of a class, go for "singleton" pattern (it can be achieved by combination of static field + private constructor).

What is the use of the enum singleton in Java?

When the Gang of four introduced the singleton pattern, they also had to explain, why not to use static class fields and method instead. The reason was: the possibility to inherit. For Java it had sense - we cannot normally inherit the class fields and methods.
Later the "Effective Java" book appeared. And we know now that the existence of reflection destroys the singularity of the singleton class with private constructor. And the only way to make a real SINGLEton is to make it as a single item of an enumeration. Nice. I had done some myself this way.
But a question remains: While we cannot inherit from enumeration, what is the use of this singleton? Why we don't use these old good static/class fields and methods?
Edit. Thanks to the #bayou.io I see that in https://softwareengineering.stackexchange.com/a/204181/44104 there is a code that can trick the enum, too, and create again two exemplars of the enum singleton. The other problems are mentioned there, too. So, there is no need to use enum instead of the usual singleton class pattern, too? BTW, all enum pluses that are mentioned here till now, work for singleton classes, too.
what is the use of this singleton? Why we don't use these old good static/class fields and methods?
Because enum is an object so it can not only be passed around but also implement interfaces.
Also since we are making a class, we can use the different public/private options available to all kinds of classes.
So in practice, we can make a singleton that implements an interface and then pass it around in our code and the calling code is non the wiser. We can also make the enum class package private but still pass it around to other classes in other packages that expect the interface.
If we used the static methods version, then the calling class would have to know that this object is a singleton, and our singleton class would have to be public so the other classes can see it and use it's methods.
There's nothing particularly wrong with the "good old fashioned singleton", enum "singletons" are just convenient - it saves you the need to muck around with boiler-plated code that looks the same in every singelton.
To me, a singleton makes sense wherever you want to represent something which is unique in its kind.
As an example, if we wanted to model the Sun, it could not be a normal class, because there is only one Sun. However it makes sense to make it inherit from a Star class. In this case I would opt for a static instance, with a static getter.
To clarify, here is what I'm talking about :
public class Star {
private final String name;
private final double density, massInKg;
public Star(String name, double density, double massInKg) {
// ...
}
public void explode() {
// ...
}
}
public final class Sun extends Star {
public static final Sun INSTANCE = new Sun();
private Sun() { super("The shiniest of all", /**...**/, /**...**/); }
}
Sun can use all the methods of Star and define new ones. This would not be possible with an enum (extending a class, I mean).
If there is no need to model this kind of inheritance relationships, as you said, the enum becomes better suited, or at least easier and clearer. For example, if an application has a single ApplicationContext per JVM, it makes sense to have it as a singleton and it usually doesn't require to inherit from anything or to be extendable. I would then use an enum.
Note that in some languages such as Scala, there is a special keyword for singletons (object) which not only enables to easily define singletons but also completely replaces the notion of static method or field.
ENUM singletons are easy to write. It will occupy very less code, which is clean & elegant if you compare with implementation of lazy singleton with double synchronized blocks
public enum EasySingleton{
INSTANCE;
}
Creation of ENUM instance is thread safe.
ENUM singletons handled serialization by themselves.
conventional Singletons implementing Serializable interface are no longer remain Singleton because readObject() method always return a new instance just like constructor in Java. you can avoid that by using readResolve() method and discarding newly created instance by replacing with Singeton
private Object readResolve(){
return INSTANCE;
}
Have a look at this article on singleton

If a class has no state, should all the methods be static?

Lets say I have a Helper class like with a few methods
public class SomeClassesHelperClass(){
public List removeDuplicatesFromTheGivenList(List someList){
// code here
}
public int returnNumberOfObjectsThatHaveSomeSpecialState(List someList){
// code here
}
}
What are the advantages / disadvantages of making the methods in this class static? Which is the better practice?
If your class provides only utility methods (like yours), I believe it's better to:
make the class final (there's no point to extend it)
define а private constructor to avoid any attempt to create an instance of the class
make all the methods static.
If you decide to make all the methods static then you need to be aware of the impact that that will have on your ability to test other classes that depend up on it.
It severely limits your options for mocking ( or at least makes it more painful )
I don't think there is a right answer to our question - it depends on what the methods do. For example, it's easy to envisage a stateless data access object - if you make all its methods static then you are building a dependency on the data source in to your test cycle, or making your mocking code much uglier
Make them static when they use no state from an object. Most of it are helper classes like Math. http://docs.oracle.com/javase/6/docs/api/java/lang/Math.html

Access singleton's fields via a static method

I have a singleton class.
When accessing the methods of the class I have the choice of two possibilities.
Create those methods as instance specific and then get the instance and invoke them
Create those methods as static and invoke them and they will get the instance
For example:
Class Test{
private int field1;
Test instance;
private Test(){};
private Test getInstance(){
if (instance == null)
instance = new Test();
return instance;
}
public int method1() { return field1;}
public static int method2() {return getInstance().field1;}
}
Now, elsewhere I can write
int x = Test.getInstance().method1();
int y = Test.method2();
Which is better?
I can think of a 3rd alternative where I use "instance" directly in the static method and then capture the exception if it is null and instantiate it and then re-invoke itself.
I could, in theory, just make the whole lot static.
However, this will create me problems when saving the state at activity close since the serialization doesn't save static.
I think the first one is cleaner.
However, keep in mind that under some extreme cases, Android may kill your static instances. See this for example: http://code.google.com/p/acra/ .
A workaround I've found somewhere for this, is to keep a reference to your singleton from the Application class, as well. I don't know how problem-proof this is, though.
You should avoid making everything static. Some people would even say that a singleton is not done.
The whole point of the singleton pattern is that you can change the implementation. In most cases you use it to keep the possibility open to "hook" in some other implementations of this functionality later.
Read: when deciding in favor of singleton plan for a setInstance method too, not just for a getInstance. - If this does not make sense, just use a plain static class.
In the other hand singletons are out of season, if you want to be hip and all that. Do a search for "eliminating global state". There are some Google-sponsored talks about it too. In short: your code will be more testable and helps you avoid some dependency chaos. (Besides being hip and all, it is definitely a step into the right direction).
In my personal opinion having static methods is bad design in the first place. It, of course, depends on the program itself, but allowing a class to have static method will have impact on the whole design. Some reasoning behind my statement:
If static method can easily change state of some object, sooner or later bugs will emerge
If you publish static method with your program, every client that will use it will have a very strong dependency on your code. If you decide to remove or change this method someday - you will break every single client that used your class.
So, if you can - avoid it.
If, from any reason, you will insist on having static method, I guess the first solution is better. That's how singleton should work. You should obtain a reference to a SINGLETON OBJECT via static method, but this object should be then used according to all principles from Object Oriented Programming.

Are there any side effect of using to many static function?

Currently i`m interesting in play framework because this framework promise faster development.
When i see the code, there are so many static code. even the controller declared as static function. Thus all the code that called inside static function must be static right?
My question is, is this approach is right? are there any side effect of using to many static function?
This question has been asked in a similar way previously. The simple answer is that Play uses statics where it is sensible.
The HTTP model is not an OO model. HTTP requests themselves are stateless, and therefore, static methods allow access to controllers as functional requests from client code.
The Model classes on the other hand are pure OO, and as a result are not static heavy.
Some of the utility methods, such as findAll or findById are static, but these again are not statefull, and are utility methods on the class. I would expect this in a standard OO model anyway.
Therefore, I don't think there is any risk in doing things in the way Play expects. It may look odd, because it challenges the norm, but it does so for sound reasons.
Couple of things about static methods in an object oriented language: Let me try to explain the problems if you choose to have all static methods.
Using all static functions may not be idiomatic in an Object oriented language.
You cannot override static functions in a subclass. Therefore you lose the ability to do runtime polymorphism by overriding.
The variables that you define all become class variables automatically (since all your methods are static), so essentially you do not have any state associated with the instance.
Static methods are difficult to Mock. You might need frameworks like PowerMock to do the mocking for you. So testing becomes difficult.
Design becomes a bit complex as you won't be able to create immutable classes as you really only have the class and no instance. So designing thread-safe classes becomes difficult.
To elaborate on my comment.
static methods can call non-static methods provided you have an instance of something.
class A {
public void nonStaticMethod() { }
public static void staticMethod(String text) {
// calls non-static method on text
text.length();
// calls non-static method on new Object
new Object().hashCode();
// calls non static method on a instance of A
new A().nonStaticMethod();
}
}
Yes there is a side effect of using too many static functions or variables. You should avoid unnecessary static declarations.
Because static members always creates a memory space once the class is loaded in the JRE. Even if you don't create the object of the class it will occupy the memory.

Categories