views:

325

answers:

6

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 ?

+3  A: 

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.

gustafc
If the "constants" need to be configurable, you could have a static initialization block that uses a Preferences database.
Steve Emmerson
This will make it hard to modify (reload) the Preferences at runtime. It will also make it impossible to unit test using different preferences.
Avi
+1  A: 

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.

unholysampler
+2  A: 

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.

Bozho
+3  A: 

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.

stacker
I'm not sure I understand what you mean by "icon loader". Is it a class providing static methods to get the icons ?
Jules Olléon
+3  A: 

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:

Bert F
A: 

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.

Yishai