What is the standard approach/best practice to creating variables that are program- or package-wide in Java?
I want to set up some global variables that are accessible by multiple classes. Examples of these global variables would be things like a boolean flag testModeOn, a language setting, current local server, time display format, etc. According to some other questions (namely this one) there aren't any global variables, but there are some work-arounds using interfaces (not recommended?) or classes. Since the original poster didn't explain their situation, they got nearly every answer under the sun and I want to ask specifically for program configuration variables.
Is it better to create a class/package/interface and then import it into my working class/package? Is there anything I should be aware of when trying to implement these variables using a separate class or interface? Is there any other way to fudge package-level variables since Java apparently doesn't do this natively?
NOTE: These variables would probably not change except when the program is re-compiled.
If you're talking about constants, then they should be declared as static final fields in a class (never in an interface, according to Joshua Bloch).
If you're talking about settings which can change on the fly, then these could be either static fields in a class, or you could create a ConfigHandler class to manage the setting and fetching of configurable values.
Using class fields for mutable values might lead to concurrency problems, so if your application is multi-threaded it might be better to create a ConfigHandler class which manages concurrent access carefully and provides synchronized methods to avoid problems.
In my opinion, the best approach to passing anything into your classes is using dependency injection. This would eliminate your need for Singletons, static constants and the likes.
Depending on which DI you favor, here are some link solutions to the problem you describe:
CDI
Spring
Guice
Create a Bean class if multiple variables are required to be used in different classes. Best practice is to create a private variable with its getters and setters.
public class ListBean implements Serializable
{
private boolean testModeOn;
public boolean getTestModeOn()
{
return testModeOn;
}
public setTestModeOn(boolean testModeOn)
{
this.testModeOn = testModeOn;
}
In general there are so many ways to do it wrong regarding this topic.
The simple way is to use a Singelton.
This is not an option - Singelton is an Anti-Pattern. http://c2.com/cgi/wiki?SingletonsAreEvil
So what is else there? An Interface with public static final variables?
Not an option - Thats simply not the use case of an interface: https://stackoverflow.com/a/2659740/1248724
so what is else there?
The answer is:
What I prefer is the spring boot way (e.g. Dependency Injection)
Here an code example which is obviously Spring.
import org.springframework.stereotype.*
import org.springframework.beans.factory.annotation.*
#Component
public class MyBean {
#Value("${name}")
private String name;
// ...
}
If you are using some similar Framework such things could be easy archived.
If that is somehow not possible in your environment I had to code something like this:
public final class Configuration {
private Configuration() {
// make sure there is no instance of this class
}
public static final MySetting<DateFormat> setting = new SampleProperty();
public interface MySetting<T> {
T get();
}
private static final class SampleProperty implements MySetting<DateFormat> {
#Override
public DateFormat get() {
return new SimpleDateFormat("...");
}
}
// other inner classes that implement the MySetting interface
}
public static void main(final String[] args) {
Configuration.setting.get();
}
Benefits:
- You can validate your properties how ever you want.
- You can work with the java security manager if you like to
Downsides:
- You may have to maintain a bunch of code (this should be easier with lambda expressions)
- Not that great as the way spring offers here for example.
A very similar approach I just found: https://stackoverflow.com/a/3931399/1248724
Related
I was prefer using static methods in my java code, since I think they are "functional""stateless" and has less side-effect. So there may be some helper classes and methods like this:
public class MyHelper {
public static Set<String> array2set(String[] items) { ... }
public static List<String> array2list(String[] items) { ...}
public static String getContentOfUrl(String url) {
// visit the url, and return the content of response
}
}
public class MyApp {
public void doSomething() {
String[] myarray = new String[]{ "aa","bb"};
Set<String> set = MyHelper.array2set(myarray);
String content = MyHelper.getContentOfUrl("http://google.com");
}
}
But my friend says we should avoid defining such static utility methods, since we call them directly in our code, it will be hard to mock them or test them if they have external dependencies. He thinks the code should be:
public class ArrayHelper {
public Set<String> array2set(String[] items) { ... }
public List<String> array2list(String[] items) { ...}
}
public class UrlHelper {
public String getContentOfUrl(String url) {
// visit the url, and return the content of response
}
}
public class MyApp {
private final ArrayHelper arrayHelper;
private final UrlHelper urlHelper;
public MyApp(ArrayHelper arrayHelper, UrlHelper urlHelper) {
this.arrayHelper = arrayHelper;
this.urlHelper = urlHelper;
}
public void doSomething() {
String[] myarray = new String[]{ "aa","bb"};
Set<String> set = arrayHelper.array2set(myarray);
String content = urlHelper.getContentOfUrl("http://google.com");
}
}
In this way, if we want to write unit tests for MyApp, we can just mock the ArrayHelper and UrlHelper and pass them to the constructor of MyApp.
I agree totally about the UrlHelper part of his opinion, since the origin static code make MyApp untestable.
But I have a little confused about the ArrayHelper part, since it doesn't depend on any external resources and the logic will be very simple. Shall we avoid using static methods at this case too?
And when to use static methods? Or just avoid using it as much as possible?
update:
We are using "TDD" in our development, so the testability of a class often is the most important concern for us.
And I just replace the word "functional" with "stateless" in the first sentence since the that's real what I meant.
You'll probably never want to mock a method that converts an array to a list (or set), and this method doesn't need any state and doesn't depend on any environment, so a static method looks fine to me.
Just like the standard Arrays.asList() (which you should probably use).
On the other hand, accessing an external URL is typically the sort of thing that you want to be able to mock easily, because not mocking it would
make the test an integration test
require to have this external URL up every time you run your tests, which you probably can't guarantee
require to have this external URL return exactly what you want it to return in your test (including errors if you want to test the event of an error).
Just beware of one disease very common amongst Java "experts": overengineering.
In your specific example, you either do or don't have a mockability issue. If you had an issue, you wouldn't be asking general questions, therefore I conclude you don't have an issue at the moment.
The general argument is that static methods are simpler and therefore the preferred choice, whenever there is a choice. A would-be instance method must first prove itself of needing to be an instance method.
If this was my project, I would defer any makeovers into instance methods until such a moment where the need for that became clear and present.
Static means you can call the method without instantiating the class. Its good if you want to package your code into a class and you have a function that just does some logic or something basic.
Just don't use a static function to try and edit member variables in the class (obviously).
Personally I think its fine to use the static function, since it is stateless.
Static methods should be used by answering the question "is this method a functionality of a specific instance?".
You shouldn't decide about a static method according to tests, you should do it according to design. Your examples doesn't need an instance because it makes no sense. So static is the better choice. You can always wrap these methods inside specific tester classes to do your tests.
The only situation in which a self-contained functionality is not static is just when you want to provide multiple implementation, so that you are forced to avoid static because you need inheritance.
I often use static methods:
for factory methods (explicitly named constructors)
to provide a functional layer above an object-oriented layer, to compose the objects
and sometimes for general-purpose functions (Apache Commons has many good examples of this)
I never use "singletons" (static objects) and methods that refer to static objects because they are a complete headache to test and reuse. I also avoid hardcoding anything into a static method that could feasibly need to be changed. Sometimes I will provide multiple methods - one with all the dependencies as parameters and others, with fewer parameters, that call the more flexible method with some default (hardcoded) values.
java.lang.Math is static which is a good example. I thought statics are not beeing garbage collected and should be avoided if possible.
No.
As mentioned by Peter Lawrey in the comment for the question, Java is all about object oriented programming. While certain functional aspects are doable and being put into eg. Java 8, at its core Java is not functional. static breaks so much of the benefits of learning how to do modern Java - not to mention all kinds of not-fun-at-all scoping problems - that there's no purpose to use them unless you're some kind of a Java wizard who really knows what happens when you use that magical keyword.
You are not a wizard. Java is not functional. If you want to be a wizard, you can learn. If you want to program in functional fashion, look into hybrid languages such as Scala or Groovy or alternatively explore the fully functional world, eg. Clojure.
Is it a violation if I go ahead with utility methods as static rather than depending on DI of spring?
I just have to maintain a hashmap like below:
private static Map<String,JMSMessage> messageMap = Collections.synchronizedMap(new HashMap<String,JMSMessage>());
messageMap can be accessed by multiple threads. I have utility methods to play around messageMap. I made my class as final and declared all utility methods as static. Is it a violation according to spring IoC?
I would argue that, even though it is possible and will work correctly in Spring IOC, it is a violation of the principals of inversion-of-control.
It would be better to use a singleton bean that is managed by your IOC than use a static field, like this
#Component
#Scope(ConfigurableBeanFactory.SCOPE_SINGLETON)
public class SimpleMessageManager implements MessageManager {
private Map messageMap = Collections.synchronizedMap(new HashMap());
#Override
void addMessage(...) { ... }
#Override
void getMessage(...) { ... }
}
You could then inject your MessageManager like this:
public class SomeBean {
#Resource
MessageManager messageManager;
}
There are many reasons why sticking to the IOC approach is better:
You may need more than one instance in future.
You can mock out the MessageManager interface in unit tests.
(Related to 2) If you use a static fields, you cannot be sure of the state of the messageMap during testing. This becomes even more complicated if you start running your tests in parallel (a standard option in Maven)
As an aside, I would recommend that you not use Collections.synchronizedMap. Have you considered using ConcurrentHashMap instead?
No it is not a violation against spring because the variable is static. Static variables are only accessible through class name. Spring IoC is useful when you want to remove dependency from the implementation, so that it can change later on without affecting anything else. In case of static variables and methods you have no choice but to access them through their class name.
And remember static variables and methods cannot be overriden.
I would like to encapsulate my fields (variables), into a different file. Like getting out the logic of my application into a different file (logic.java ?), where every class could access the variables that should be "global".
Netbeans is capable of doing encapsulation, but it will just put a list of setter/getter functions into the same file.
(Later, I would like to call the functions with Logic lo = new Logic();, and lo.getValue(), for example.)
If there is a better way of doing this, please enlighten me, and I'll delete the question. (The classes are in different package. app.logic; app.desk; app.net, etc.)
What you want here are advanced refactoring capabilities, and for that I'd suggest you take a look at IntelliJ IDEA (The community edition is free to use and download and is available for all platforms).
Take a look at it here.
I don't know if I understand correctly but what you can do is implement a singleton class:
public class Singleton {
private static Singleton instance = new Singleton();
private Singleton() {
}
public static Singleton getInstance() {
return instance;
}
// members, getters and setters
}
Now this guarantees that you only have one instance of Singleton in your entire application that can be obtained anywhere with Singleton.getInstance().
I have a Preference class (module) that's used across several different apps. Basically it's a cache of the preferences so that the systems don't have to call the backend all the time. It's similar to a cache but with some additional niceties such as isPreferenceSelected, has some helper methods, etc.
The issue is that I'd like to include a savePreference within the class so that whoever uses it can just override that method, be it to a database, to a flat file, etc. The key is that this module just doesn't want to care. The issue is that it's not an abstract class so I can't override the static methods and even if it was, I don't want to create a million instances because I don't want to load the preferences each time. And I can't create a abstract singleton either.
Therefore I'm not sure what to do. Here is a code snippet of what I'd like to do with comments:
// Please ignore the missing Generics, etc.
public class Preference
{
private static HashMap preferences = new HashMap();
public static ...
// Some preferences are objects, such as images, etc.
public static setPreference(String name, Object value)
{
.. some helper code
preferences.put(name, value); // ignoring issues with if it already exists ;)
savePreference(name, value); // saves to database, flatfile, etc.
}
}
That was the core class/code that the different systems leverage. Now what I'd like to do is say in a webapp, a desktop app, etc., be able to use this class in my code such as:
public someFunction(...)
{
.. do some cool code
Preference.savePreference("logoImage", image);
}
And have the savePreference() method not just save the in-memory preferences, but also save it to the external source. Otherwise everywhere I have savePreference() I have to follow it by a db call savePreferenceToDB(), a FlatFile call such as savePreferenceToFlatFile(), and so on. This is very error prone, someone somewhere will forget to save it. Plus it really makes no sense to sprinkle the save to permanent storage code everywhere with this type of code when it should really only be done once. Also remember that the main module has no idea if the permanent storage is a database, an xml file, a flat file, etc.
Hint: If I did Preference.getInstance().savePreference() that wouldn't work because you can't abstract a singleton. And I can't create a static method savePreference() because it's not possible to override a static method.
The only options I can see is to create some kind of complex Factory pattern, but that seems like a lot of overkill to me. Therefore any suggestions would be greatly appreciated.
This sounds like something that your dependency injection (DI) container should be handling, not a complex factory pattern.
That is, I think you should ditch the usages of static, have whatever creates the other applications inject an instance of Preference into your applications. You can do this without a DI framework if you just take the Preference as a parameter in your constructor for whatever other classes depend on it.
Edit: Let me give you an example of dependency injection without a framework. Take the following set of classes:
public class Preference
{
private String userName;
public Preference(String userName)
{
this.userName = userName;
}
public void savePreference()
{
// Default implementation saves it to the screen. ;-)
System.out.println(userName);
}
}
public class Foo
{
private Preference p;
public Foo(Preference p)
{
this.p = p;
}
}
public class Bar
{
private Preference p;
public Bar(Preference p)
{
this.p = p;
}
}
public class Main
{
public static void main(String[] args)
{
Preference p = new Preference("Mike");
Foo f = new Foo(p);
Bar b = new Bar(p);
}
}
This is a simplistic example, but it satisfies your requirements:
The Preference instance is only created once
The Preference class can be extended by whoever implements the Main class to instantiate whatever kind of Preference subclass they want to, if they wanted to persist it in a relational database (or whatever)
By avoiding having static calls in the first place you also make it possible for your someFunction() example to be unit tested without pulling in a potentially big, complicated preferences framework. Rather, someone implements a mock Preference subclass and passes it into the class that runs someFunction(). Your code will be much more testable that way.
#Mike says:
... I think you should ditch the usages of static
#Stephane responds:
... what is the major issue with static methods?
It is not just static methods. It is also the singleton instance.
Basically, they are inflexible:
They make it difficult to do things in alternative ways, as illustrated by your problem. If you didn't use a static method and a private singleton instance, you could create a Preferences interface and/or abstract base class, together with implementations that load and save the in-memory preferences in different ways.
Static instances tend to make testing harder. For instance, if you had a preferences UI that made use of your Preferences class, you couldn't unit test the UI classes using a "mock" version of Preferences. (Or at least, it would be a lot harder to do.)
Statics tend to make it difficult to reuse your code because of the hard dependencies on specific named classes and specific implementations.
Statics are non-OO. This is not intrinsically a bad thing, but it does mean that you can't make use of the nice properties of OO ... like overriding and polymorphism ... when you use statics.
If you have a significant number of these static methods / static objects in your application, a DI framework is a good solution. But as #Mike says, using Factory methods and passing objects in constructors will work just as well in many cases.
You commented:
One of the reasons I have it as a static class is because the preferences are loaded at startup. After that they stay in memory in the one static object. With DI, each time I create the object, I'd have to reload the information into memory from the data source. This defeats the whole purposes of having a Preferences Object (that pretty much acts like a cache with benefits).
This does not require you to use a static instance.
With DI (or explicitly wiring instances via constructors), you don't create the Preferences object more than once. You create it once, and then inject it as many times as required.
There is a halfway between your current approach with a static method that wraps a static instance of a hard-wired class and full DI. That is a what can best be described as a static holder; e.g.
public interface Preferences {
// Preferences API
}
public abstract class PreferencesBase implements Preferences {
// Implement as much if the API as makes sense
}
public class FileBackedPreferences extends PreferencesBase {
// Implement (protected) persistence methods.
}
public class DatabaseBackedPreferences extends PreferencesBase {
// Implement (protected) persistence methods.
}
public class ApplicationPreferences {
private static Preferences instance;
private ApplicationPreferences() { }
public Preferences getInstance() { return instance; }
// Call this once during application startup with the
// Preferences instance to be used by the application.
public void initPreferences(Preferences instance) {
if (this.instance != null) {
throw new IllegalStateException(...);
}
this.instance = instance;
}
}
I think it might take some rework of your design (unfortunately, I don't have a decent whiteboard in my apartment yet, so I can't easily sketch things out to conform), but I immediately thought Strategy pattern as soon as you said this:
The issue is that I'd like to include a savePreference within the class so that whoever uses it can just override that method, be it to a database, to a flat file, etc. The key is that this module just doesn't want to care.
You might have an abstract Preferences class that has every method but saving (and loading) implemented. In the sense of the pattern, this would be the Strategy interface. Your different types of saving and loading would be handled by the concrete implementations.
Create an interface for your preference manipulation class:
public interface PreferenceHandler {
void savePreference();
void readPreference();
}
Pass an instance of type PreferenceHandler to your class with all the static methods.
Invoke the methods on that class within your class.
Though, not lovin' all those static methods. It's probably why you're having so many issues here. Create a factory that gives you a copy of the class if you don't want to be creating lots of copies of it. But static methods really impede code re-use and extension. Or perhaps use a framework like Spring to manage classes of this sort.
I have an encryption utility method that relies on an external dependency --- a cipher key which is being retrieved from a property file. The way it can be retrieved in the current code base which I inherited is that it relies on creating new objects to be able to get the value of a property in the properties file. For example, if wanted to get the Cipher Key from the property file, it would be like this:
public synchronized static String encrypt(String someTextToEncrypt) {
String propertyValue = null;
propertyValue = getProcessCommonBase().
getProcessProperties.getProperty("CIPHER_KEY");
/*encrypt algorithm*/
return encryptedForm;
}
private synchronized static ProcessCommonBase getProcessCommonBase() {
if (processCommonBase == null) {
processCommonBase = new ProcessCommonBase();
}
return processCommonBase;
}
private static ProcessCommonBase processCommonBase;
EDITED: Design-wise is having a something like the processCommonBase instance variable a good practice to do? My understanding is that a good practice is that static variables should be final and do not change. In this case, however, the ProcessCommonBase class maintains state and is subject to change.
NEW QUESTION: If the static method relies on something external shouldn't I just mark the method and the processCommon base variable as non static and in Spring, just make a bean definition for it? What is better?
I agree with Joonas. I don't see why not make the variable final. Could you elaborate please what exactly do you mean by this:
My understanding is that a good practice is that static variables should be final and do not change. In this case, however, the ProcessCommonBase class maintains state and is subject to change.
Even if the variable is final, you still can change the object it references to in exactly the same ways as you'd do it with a non-final variable. That's why it's perfectly fine for a static method to have a static variable maintaining its state, but nothing stops you from actually making it final in this case. Why not do this:
private static ProcessCommonBase processCommonBase = new ProcessCommonBase();
Maybe there's something stopping you from creating processCommonBase at static initialization time, but it isn't obvious from the information you have provided.
Someone already commented your specific case, but in general, what you described is an effectively final static variable, which is just created "lazily" (that is, only when needed). It's a fine approach, if creating a ProcessCommonBase instance is an expensive and rare event, although you must be careful to access it only via the getter method then. On the other hand, if a ProcessCommonBase will be created whenever the surrounding class is used, then making it actually final is a better approach: it's simpler (less error prone, as you don't need to remember to use the getter method exclusively), and will actually be a bit cheaper, as the final variable is initialized only when the surrounding class is first used, and you don't need the (synchronized!) null check every time when accessing it (of course, if you use > 1 threads andProcessCommonBase isn't thread-safe, then you need to synchronize somewhere).
Answer to your second question: being static vs. not and relying on some external system properties are two separate things. I don't know what Spring does, but if your method essentially a function - "value in, result out" - then it's a static method by its nature, even if it reads its configuration from some system property. Making such methods instance methods is possible, but if it only complicates things and gives nothing, why bother?
The usage of static is often frowned upon from an OO design perspective because it gives tight coupling between objects. With statics methods it’s impossible to decouple an interface from its actual implementation. This lack of decoupling can for example become a problem when you want to unit test a single class, as it can’t be separated from the other static parts.
In today’s Java landscape you’re singleton crypt class can be much better designed with the help of Dependency Injection (DI). The ProcessCommonBase could also be implemented as an DI singleton if it didn’t had that very strong code smell, because if it’s a god-object then it should be refactored, for example by using DI for injecting properties into you crypt class.
Example code based on Google Guice:
#Singleton
public MyCrypt {
private final key;
#Inject
MyCrypt(#CipherKey String key) {
this.pBase = pBase;
}
public synchronized String encrypt(String someTextToEncrypt) {
/*encrypt algorithm*/
return encryptedForm;
}
}
Configuring DI properties:
public class PropertiesModule extends AbstractModule {
#Override
protected void configure() {
String key = .. what ever ..
bind(String.class).annotatedWith(CiperKey.class).toInstance(key);
}
More DI examples can be found here:
http://java.dzone.com/articles/cdi-overview-part-1
Populair Java DI implementations are: Guice, Spring and Java EE6.