Java 2D game: Where to put "global" non-final variables - java

I am working on a Java 2D game for which I am using AWT graphics, a JFrame and a JPanel. I would like to know where I should store some non-final but globally accessible (I need to be able to read/change these variables from every other Object/Class) variables to coordinate e.g. the width and height of the game's panel, which I want to be able to change in a little settings menu within the game.
At the moment, I am storing these variables in a separate interface which most of my other classes implement, but this means I cannot change the variables as they are all final.
As I see it I have two options:
Put all these variables as static, non-final ones in my main game class and access them via Game.PanelWidth
OR
Create a separate class just for these variables and access them like this: Variables.PanelWidth, where "Variables" would be that new class' name.
Which method is better, or should I use a completely different approach?

Without going through your code, it's hard to provide a specific response.
General recommendations:
At the moment, I am storing these variables in a separate interface which most of my other classes implement, but this means I cannot change the variables as they are all final.
It's not a good idea to use inheritance to access your settings. For this reason alone I think either of the options you're considering is an improvement as it uses composition instead of inheritance.
You should consider applying the Single Responsibility Principle.
Who is responsible for managing your game's settings? Maybe a Properties object.
Who is responsible for constructing such an object? Maybe the main method.
If you apply this principle, hardly any of your classes should require access to the PanelWidth property.
Specific recommendations:
Java provides a Properties class. This class is both thread safe and easy to use when loading/storing properties to files.
From the Javadoc:
This class is thread-safe: multiple threads can share a single Properties object without the need for external synchronization.
Rather than creating a static properties object, consider constructing the properties object in the main method (basically, poor-man's dependency injection)

The choice is largely up to you and should be driven by a balance between complexity and the actual needs of the application.
The interface you mentioned is a known anti-pattern Constant Interface - generally frowned upon because you litter the inheritance tree and namespace everywhere with information that should remain encapsulated. It does work though and in small projects it may be acceptable.
A separate class is a better approach, it solves at least the namespace litter. Make its constructor final to prevent accidental subclassing.
Generally, static members can work in small projects, but it can turn out to be impossible in case the project grows and it turns out that the variables aren't really application global, but only use-case global. Refactoring such a case can create a lot of work later.
Using an actual instance of the "global" settings class prevents this from the start, the cost is that you need to pass the instance around to where it needs to be accessed (e.g. as constructor parameter).
Next is threading and the issue of communicating changes to those global variables. Unless your application is running in a single thread (that would be the case in a purely event driven swing application), you cannot simply make changes to values and expect the change to take effect properly at every dependency site (imagine just having read panelWidth, but before you can read panelHeight new dimensions are set). You need a way to prevent these situations. So simple members are out. You'll want get/set methods that ensure only complete information is read and that writes of related values are atomic.
The atomicity can be ensured by encapsulating related values into a composite object, e.g.: Instead of panelWidth, panelHeight you have a panelDimension. No getters/setters for the individual values, are provided. You can only get the entire Dimension (for reads) or replace it with a new dimension (for writes). The actual member can be either volatile, of the AtomicReference variety or protected by making getter/setter synchronized.
To properly communicate changes to every dependency site, you may need some notification mechanism, so either the entire global state or individual parts of it may need the ability to register listeners and notify those listeners on changes (again threading issues are to be considered, since listener callbacks are usually implemented on the thread making the change, which may need consideration in the listener called).

Related

How to maintain a centralized Object across the application

I am developing an application where I need to create an object and multiple classes have to access and modify that object. How to see the recent changes made by the other class object and how to access the object centrally through all the classes with out passing that object as a parameter across all the classes?
I am creating an Apache POI document where I am adding multiple tables, multiple headers/footers and paragraphs. I want only a single XWPFDocument object present in my application.
Is there any design pattern we can achieve this?
Well the singleton design pattern would work - but isn't terribly clean; you end up with global static state which is hard to keep track of and hard to test. It's often considered an anti-pattern these days. There are a very few cases where it still makes sense, but I try to avoid it.
A better approach would be to use dependency injection: make each class which needs one of these objects declare a constructor parameter of that type (or possibly have a settable property). Each class shouldn't care too much about how shared or otherwise the object is (beyond being aware that it can be shared). Then it's up to the code which initializes the application to decide which objects should be shared.
There are various dependency injection frameworks available for Java, including Guice and Spring. The idea of these frameworks is to automatically wire up all the dependencies in your application, given appropriate configuration.
There is Singleton Pattern for this, it creates a single instance for the application and is shared without passing around.
But it not not the best of options.
Why is it a bad option?
It is not good for testability of code
Not extensible in design
Better than Singleton Pattern is an application wide single instance
Create a single object for the application and share it using some context object. More on this is explained by Misko in his guide to testable code
single instance and not Singleton Pattern
It stands for an application wide single instance, which DOES NOT inforce its singletonness through a static instance field.
Why are Singletons hard to test?
Static access prevents collaborating with a subclass or wrapped version of another class. By hard-coding the dependency, we lose the power and flexibility of polymorphism.
-Every test using global state needs it to start in an expected state, or the test will fail. But another object might have mutated that global state in a previous test.
Global state often prevents tests from being able to run in parallel, which forces test suites to run slower.
If you add a new test (which doesn’t clean up global state) and it runs in the middle of the suite, another test may fail that runs after it.
Singletons enforcing their own “Singletonness” end up cheating.
You’ll often see mutator methods such as reset() or setForTest(…) on so-called singletons, because you’ll need to change the instance during tests. If you forget to reset the Singleton after a test, a later use will use the stale underlying instance and may fail in a way that’s difficult to debug.

Private Class Variables vs Excessive Argument Passing

I am currently working on a single activity Android app that uses a lot of shared UI objects (like Button, etc). At the moment, I have these UI objects declared as private non-static class variables. The alternative to this would be to continually pass the objects from method to method and modify them that way. It is currently unclear to me which option should be preferred, as it seems to me that using the maximum encapsulation form would cause me to do quite a bit of argument passing. Can anyone shed some light on this?
Generally I like to think of encapsulation as hiding data within a single class. If multiple methods are accessing that object within the class, that doesn't really violate encapsulation principles. Once you start leaking it outside the class, that's when encapsulation problems occur.
With that said, it is perfectly fine to have a private member which is a Button and multiple methods can access that button.
As above Jeff said You should go for passing arguments as you are inside one activity as you have mentioned in your question and encapsulation is always the first thing to be recommended.I will suggest to do one more thing if you can :
Define one function which will accept the color code or color type, and call this function from all the functions where you want to change the button text color.In this way code can be in one place which is performing the same operation i.e. changing the color.
It depends if those private non-static variables that you want to pass as arguments actually make sense to become the properties of the class.If you think it makes sense and have design control over their updation/modification you can go ahead and declare them as class members

Make java methods visible to only specific classes

I have a manager class that is responsible for managing Objects of a certain kind. To do so it needs to manipulate these Objects, but these Objects have no relation to the manager whatsoever, so design technically, they are in separate packages "project.managers" and "project.objects" . The important thing is that the Objects in question should only be manipulated by the managers and nowhere else, but need to be accessible by every other class in the project.
As such I'd like to have the managers have access to manipulating methods, but restrict access to every other class. The most obvious one would be to move the manager class and object class into the same package and declare manipulating methods protected, but as the managers and objects are completely separate entities they don't fit there philosophically.
(This is partly because I want my IDE to stop showing me the manipulating methods whenever I autocomplete code on the Objects in question so I always have to go the route through the manager so corresponding tables are correctly updated whenever I change the Objects in question).
Are there any ideas to that or is the obvious way the best in any case?
Why not have an interface called
ManagerFunctions
and another called
ClientFunctions
You managed objects will implement both of these.
When you create the managed objects, you pass them around, but only as references to ClientFunctions. The manager objects will, however, refer to them as ManagerFunctions and consequently have access to their 'managed' functions. The appropriate casting will simply expose the appropriate methods.
Your IDE will automatically present you wil the appropriate methods depending on how these objects are referenced.
You're asking for something akin to the "friend" declarations of C++, but there's no direct equivalent in Java - package visibility is the nearest. Alternatively you could go for a model like the XML DOM, where the methods that should be public are defined in interfaces and all client access is via these interfaces. The manager would know the concrete class of the implementation so could downcast to that as required.
As such I'd like to have the managers have access to manipulating methods, but restrict access to every other class. The most obvious one would be to move the manager class and object class into the same package and declare manipulating methods protected...
Technically, you would declare the manipulating methods package protected (no modifier at all). Protected methods allow the class to be extended easier.
but as the managers and objects are completly seperate entities they don't fit there philosophically.
I understand. Java doesn't have the "friend" declaration that C++ has.
You could comment the manipulating methods, but that doesn't solve your Eclipse problem.

when is a singleton class preferred over a class that has only static methods?

When is a singleton class preferred over a class that has only static methods and a private default constructor?
Please vote.
Use a singleton to better control when initialization occurs. With a static class, any initialization must be at class load-time, which you have little control over. For example, a simple reference to a static final MEMBER will trigger class loading. With a singleton, initialization can trivially be deferred till much later - typically, till first time of use.
Reasons to delay initialization may be:
it's expensive and you don't always need it for that class
you can't initialize till some other resource is initialized (say, a database connection). In this case, a lazily-instantiated singleton often provides correct order of operations without any explicit control - if it's not referenced till after the other resource is initialized, everything happens for free.
Use a singleton to improve testability. If you need to make some kind of mock object (in the broad sense) of the singleton in order to test its clients, one way to do it is to put an interface on its use, and supply a test singleton that's of a different class but implements the same interface.
Using a singleton makes initialization testing easier as well.
Use a singleton when you might need to debug initialization. Stack traces from static initialization can be puzzling. Debugging can be puzzling too. If the class is loaded early, it may break before a breakpoint on the first line in main() is even hit.
When is a singleton class preferred over a class that has only static methods and a private default constructor?
When you need an instance. For example, to pass as method argument.
The main reason for only having static methods is when you just need a toolbox to pack some functions together.
I use singletons for mainly two reasons:
It is really expensive (time or memory) to construct the object, and
I want to only ever do it once.
The data associated with the class
needs to be the same in every instance of the class.
If you have some state you need to store, a singleton is the way to go. For instance, if your class needs to load some configuration from a properties file.
Static method is not dynamic, this is a big different with singleton class instance. So if you need to extends from a class and override some method, the second way won't work.
And the for the second way, you may need to use some static references which may lead to memory leak.
I would say that a singleton class would be preferred only in one case: when you have some configuration to store that is system wide, will rarely (if ever) need to be refreshed.
As an example of what I mean, I have a singleton pattern in one of my applications that represents the NAT device of the user's internet connection. This application is intended for desktop use, and so would rarely (if ever) see a change in the internet connection. Presumably the user could carry their laptop to a new location, and this would change; however, there is a method to recreate the state in this event, but this is very infrequently changed state that can take several seconds to initialize.
This need to keep expensive, infrequently changing, and globally applicable state is best done by either an application scoped bean (my preferred option) or a singleton pattern bean. Static methods aren't as good for preserving this kind of state, though you could also accomplish this using static fields as well to make a pseudo-singleton. (Not sure if there's a better name for this - probably)
In general, my recommendation is not to use singleton like patterns if you can avoid it, as it makes re-use more difficult. If you're using a CDI framework, scope your bean at the application level for easier re-use. (This may not be a concern of yours - if not, you may safely ignore this advice)

Where to store global variables like file paths in java?

In my application I use some icons. Where should I store the path of the directory containing those icons ?
The icons are used in different classes so it doesn't really make sense to store them in one of those classes in particular.
I read that global variables are evil, but is it acceptable to use a class (eg Commons) containing only public static final fields to store this king of data ? What solution is used in professional applications ?
Global Constants
As others state, global constants don't have the same negative connotation as global variables. Global variables make a program difficult to debug and maintain because of uncontrolled modifications. Global constants (public static final) don't create the same problem
Nevertheless, object-orientation is about binding code close to its data to enhance understandability and maintainability. You still have to find the right balance between storing global configuration values in a global class vs keeping data close to the code that will use it.
It is probably also worth reminding here that, because the compiler may inline some constants, if you change a constant value, you may have to recompile and redeploy more than just the class that contains the constants.
Externalizing Values
You also asked about what professional apps do. Its not uncommon for those apps to make these types of values, like files paths, externally configurable. It depends on how likely the value is to change (i.e. how likely your app will move or your code will be used in another app) and how convenient or easy it is to recompile and redeploy the code with new values. If you do choose to make some values externally configurable, you still may want to encode default values for those items in the code.
Here are some ways to externalize those values and some links to get you started. This is of course not an exhaustive list:
System properties so you can specify them on the command line
Property files [See StackOverflow Q - How to use java property files?]
Resource Bundles [See StackOverflow Q - How to load a resource bundle from a file resource?]
Global variables are evil (since they make it nearly impossible to figure out who modifies what), but constants aren't evil. public static final String fields are fine, since they can't be modified.
I would recommend to include them (the icons) with your class files in a jar, say a folder called resources and only the icon loader needs to know the resources folders name within your jar.
You are referring to constants, not global variables, so don't worry about them being evil - they are not, because they don't change.
if they are used by one class - place them in that class
if they are used by multiple classes in one package - place them in a special class
if they are used by multiple classes and they logically belong somewhere, place them there.
Have in mind that in case these "constants" are actually configurable, you'd better pass a Configuration object to methods that need it. Well, you may have the static somewhere, but from testability point of view it is a must to inject them / pass them.
Global variables are not the same as global constants. The reason global variables are bad is because they can be changed anywhere in the code and it is very hard to track down errors that result from a global variable not being in the expected state. Global constants will always be in their expected state because they can never be changed inadvertently.
In general I would suggest that this particular case be a packaging problem and to not reference the items as files on the file system, but rather as elements in the classpath, and load them via a classloader. This requires setting their location in the classpath of your application.
Then there should only be one class that knows how to retrieve these icons, and all other code asks that class for the icons it needs.

Categories