Legitimate uses for static initializer? - java

I remember a couple years ago I was using static initializers to call class-level setup operations. I remember it having very bizarre behaviors and I just decided to steer clear from them. Maybe it was because I was messing up the top-bottom order or being a newbie. But I am encountering a need to revisit them and I want to make sure there is not a better way that is just as concise.
I know it is not fashionable, but I often have data-driven classes that maintain a static list of instances imported from a database.
public class StratBand {
private static volatile ImmutableList<StratBand> stratBands = importFromDb();
private final int minRange;
private final int maxRange;
private static ImmutableList<StratBand> importFromDb() {
//construct list from database here
}
//constructors, methods, etc
}
When I have dozens of table-driven classes like this one, this pattern is very concise (yes I know it tightly couples the class with one source of data/instances).
However, when I discovered the goodness of Google Guava I want to use the EventBus to update the static list when a certain event posted. I would create a static final boolean variable just to call a static method that initialized the registration.
public class StratBand {
private static volatile ImmutableList<StratBand> stratBands = importFromDb();
private static final boolean subscribed = subscribe();
private final int minRange;
private final int maxRange;
private static ImmutableList<StratBand> importFromDb() {
//construct list from database here
}
//constructors, methods, etc
private static boolean subscribe() {
MyEventBus.get().register(new Object() {
#Subscribe
public void refresh(ParameterRefreshEvent e) {
stratBands = importFromDb();
}
});
return true;
}
}
This got annoying very quickly, because the compiler would throw warnings over the subscribed variable never being used. Also, it just added clutter. So I'm wondering if it is kosher to use the static initializer, and there really is no better way if I do not decouple this into two or more classes. Thoughts?
public class StratBand {
private static volatile ImmutableList<StratBand> stratBands = importFromDb();
static {
MyEventBus.get().register(new Object() {
#Subscribe
public void refresh(ParameterRefreshEvent e) {
stratBands = importFromDb();
}
});
}
private final int minRange;
private final int maxRange;
private static ImmutableList<StratBand> importFromDb() {
//construct list from database here
}
//constructors, methods, etc
}

So I'm wondering if it is kosher to use the static initializer
The funny thing is that
private static final boolean subscribed = subscribe();
and
private static final boolean subscribed;
static {
subscribed = subscribe();
}
get compiled to exactly the same bytecode. So using the needless static variable is strictly worse.
But until we are ready to scale up to a DI-driven framework,
Discover Guice. Don't call it framework (though it is). It's easy to use and let's you get rid of static.
Or do it manually. Rewrite your class by dropping all static modifiers and pass it everywhere you need it. It's rather verbose sometimes, but stating dependencies explicitly allows you to test classes in isolation.
The way it is, you can't test StratBand without hitting the database, no matter how trivial the method under test is. The problem is the coupling of every StratBand instance to the list of all StratBands.
Moreover, you can't test the behavior dependent on the stratBands contents as it always get loaded from the DB (sure, you can fill your DB correspondingly, but it's a big pain).
For starters, I'd create StratBandManager (or StratBands or whatever name you like) and move all the static functionality to it. In order to easy the transition, I'd create a temporary class with static helpers like
private static StratBandManager stratBandManager = new StratBandManager();
public static ImmutableList<StratBand> stratBands() {
return stratBandManager.stratBands();
}
Then deprecate it all and replace it by DI (using Guice or doing it manually).
I find Guice useful even for small projects. The overhead is tiny as often there's no or hardly any configuration.

Related

Static to non-static refactoring, can't have both?

I have a refactoring situation that I cannot find an elegant solution for...
Disclaimer:
Keep in mind that I am oversimplifying this example to reduce clutter, and not disclose things I am not allowed to disclose :)
As such, please do not assume that this is the ONLY code in my giant codebase, and offer solutions that cut corners or change parts of the design that I mention cannot be changed due to outside constraints.
The facts:
I have a utility class, it has a bunch of static methods, they utilize a singleton resource:
public final class Utility
{
private static final Resource RES = Resource.getInstance();
private Utility() {} // Prevent instantiating Utility
public static boolean utilMethodOne() { return RES.isSomething(); }
public static int utilMethodTwo() { RES.getNumThings(); }
...
public static void utilMethodInfinity() { ... }
}
Utility is in a library JAR that is used by several applications in a large codebase -- let's say on the order of 10,000 calls to its static methods, e.g.: if(Utility.utilMethodOne()) { ... }
Resource is an outside class from another library JAR.
Resource also has a method Resource.getInstance(String name) that will return a named instance, which may relate to a different underlying resource based on the name (internally it keeps the named resources in a Map<String,Resource>).
Resource.getInstance() returns the equivalent of Resoruce.getInstance(""), aka the default instance.
The situation:
The Utility needs to be enhanced to now execute against one of several resources, so my plan is to make the Utility an instantiable class with a non-static Resource member variable. Something like this:
public final class Utility
{
private Resource res;
public Utility(String resName)
{
this.res = = Resource.getInstance(resName);
}
public boolean utilMethodOne() { return this.res.isSomething(); }
public int utilMethodTwo() { this.res.getNumThings(); }
...
public void utilMethodInfinity() { ... }
}
Now all this is great, and I can start creating Utility objects that access their specified resource instead of just the default one. However, as I mentioned, there are 10-100K method calls that are now invalid as they were calling static methods!
The problem:
My plan was to keep the static methods in Utility, and have them use the default instance from Resource, while adding in non-static variants for the instantiated Utility objects that use their "local" resource reference.
// Best of both worlds:
public static boolean utilMethodOne() { return RES.isSomething(); }
public boolean utilMethodOne() { return this.res.isSomething(); }
Maybe I can't have my cake & eat it too:
error: method utilMethodOne() is already defined in class Utility
public static boolean utilMethodOne(String sql)
So it seems I am going to have to either...
Introduce a whole new BetterUtility class for places that want to use the named-resources.
Update 10,000 places to instantiate & use the revised Utility object.
...? (hint: this is where your suggestions come in!)
I really don't like 1 or 2 for a variety of reasons, so I need to ensure there is no better 3 option before settling. Is there any way to retain a single class that can provide both the static & non-static interfaces in this case?
UPDATE 2020-06-01:
I am coming to the realization that this magical option 3 doesn't exist. So out of my original two options I think #2 is best as it's just one time "just get it out of the way and be done with it" type effort. Also incorporated some of your suggestions in the design(s).
So now that I have a direction on this, I am left with [hopefully only] one more key decision...
Update all the calls to create new objects
// For a one-off call, do it inline
boolean foo = new Utility("res1").utilMethodOne();
// Or when used multiple times, re-use the object
Utility util = new Utility("res1");
boolean foo = util.utilMethodOne();
int bar = util.utilMethodTwo();
...
Given the amount/frequency of usage, this seems like a whole lot of wasted efforts creating short-lived objects.
Follow the pattern that Resource itself uses, creating my own named-singleton map of Utilities (1:1 with their respectively named Resource)
public final class Utility
{
private static final Map<String,Utility> NAMED_INSTANCES = new HashMap<>();
private Resource res;
private Utility(String resName)
{
this.res = Resource.getInstance(resName);
}
public static Utility getInstance(String resName)
{
synchronized(NAMED_INSTANCES)
{
Utility instance = NAMED_INSTANCES.get(resName);
if(instance == null)
{
instance = new Utility(resName);
NAMED_INSTANCES.put(resName, instance);
}
return instance;
}
}
public boolean utilMethodOne() { return this.res.isSomething(); }
public int utilMethodTwo() { this.res.getNumThings(); }
...
public void utilMethodInfinity() { ... }
}
// Now the calls can use
Utility.getInstance("res1")
// In place of
new Utility("res1")
So essentially this boils down to object creation vs. a synchronization + map lookup at each usage. Probably a little bit of premature optimization here, but I'll probably have to stick with this decision long term.
UPDATE 2020-06-29:
Didn't want to leave an "Internet dead end" here...
I did eventually get all the call sites updated as described above (including option #2 from the 2020-06-01 update). It has made it through all testing and been running in production for a week or so now in various applications.
It seems that you may want to turn the Utility into a singleton map that will have the same static methods that access the singleton without any arguments on for the function invocations (just like you have now)
The singleton will support a static method of adding a new resource, you will then add it to the map.
In addition you can overload the existing methods to also accept an argument resource name, that will then use a particular resource from the map, otherwise will use the default entry from the map.
Keep the old methods and the new methods static.
private static final String DEFAULT = "RESOURCE1";
private static Map<String, Resource> resources = new HashMap();
static{
// initialize all resources
}
public static boolean utilMethod() { return resources.get(DEFAULT).isSomething(); }
public static boolean utilMethod(String resourceName) { return resources.get(resourceName).isSomething(); }

Should constant details be part of the abstraction or the implementation?

I have a SaveSettings network operation in my application.
I am using an adapter so that I can be free to plug in another networking library in the future and not change any of my code.
public interface SaveSettingsOnServerAdapter {
void saveSettings(User user, OnSaveSettingsOnServerListener listener);
}
public class SaveSettingsOnServerAdapterImpl implements SaveSettingsOnServerAdapter {
private static final String API_USER_SESSION_HEADER = "Cookie";
private static final String API_SAVE_SETTINGS_PATH = "user/{user_id}/update";
private static final String API_SAVE_SETTINGS_USER_ID_PATH_PARAMETER = "user_id";
private static final String API_SAVE_SETTINGS_SYNC_WITH_CALENDAR_PARAMETER = "sync_with_calendar";
private static final String API_SAVE_SETTINGS_USE_MOBILE_NETWORK_PARAMETER = "use_mobile_network";
#Override
void saveSettings(User user, OnSaveSettingsOnServerListener listener) {
// Some implementation here, in my case - RETROFIT
}
}
My gut feeling tells me that those details outlined in the constants defined in the Implementation class are independent of whatever networking library I choose to use for the networking, so they should be part of the abstraction, right?
If so, should I declare SaveSettingsOnNetworkAdapter abstract and insert them there? And then SaveSettingsOnNetworkAdapterImpl extend it instead of implement it? Is it a problem to extend an abstract class instead of implementing an interface when employing the Adapter pattern?
Downgrading an interface to an abstract class isn't unproblematic. You force all future implementations to extend that class and only that class, whereas currently you can attach the interface to almost anything.
Plus, the parameters may be constant (as far as you can tell now) but is it really the responsibility of a SaveSettingsOnServerAdapter to keep & define them?
They are required in there for sure. But requirements can be provided by other places as well. The most versatile / abstract solution to that is to define another interface that provides the values and to add the dependency to that interface to the constructor of every SaveSettingsOnServerAdapter implementation.
If you don't like to repeat that constructor, that would be a good place to make an abstract class that implements SaveSettingsOnServerAdapterImpl and covers the common code to deal with the external interface.
But it's up to you. Whether you want more encapsulation and to which degree you want that depends on what you're working on. In a tiny tool that isn't going to change is pointless since abstractions aim to make change easy. And more abstraction also means more code and more code means more places that can break.
public interface ServerConfiguration {
String getHeader();
String getPath();
...
}
public enum DefaultServerConfiguration implements ServerConfiguration {
INSTANCE;
private static final String API_USER_SESSION_HEADER = "Cookie";
private static final String API_SAVE_SETTINGS_PATH = "user/{user_id}/update";
...
#Override
public String getHeader() {
return API_SAVE_SETTINGS_PATH;
}
#Override
public String getPath() {
return API_SAVE_SETTINGS_PATH;
}
...
}
public class SaveSettingsOnServerAdapterImpl implements SaveSettingsOnServerAdapter {
private final ServerConfiguration config;
public SaveSettingsOnServerAdapterImpl(ServerConfiguration config) {
this.config = config;
}
#Override
void saveSettings(User user, OnSaveSettingsOnServerListener listener) {
new Request().withHeader(config.getHeader());
}
}
public class UserOfAllThis {
new SaveSettingsOnServerAdapterImpl(DefaultServerConfiguration.INSTANCE);
}
The idea of abstraction is to make your code more generic. This should hide implementation as much as possible. Adding constants to the abstract layer will reveal some implementation details. The best way will probably be to add the constants to the implementation class or create a new class with these constants.

What if the benefit of using a final instance in the classic singleton pattern (if any)?

In the below snippet, Singleton1#INSTANCE is not final, while Singleton2#INSTANCE is:
public class Singleton1 {
private static Singleton1 INSTANCE = new Singleton1();
private Singleton1() {}
public static Singleton1 getInstance() {
return INSTANCE;
}
}
public class Singleton2 {
private static final Singleton2 INSTANCE = new Singleton2();
private Singleton2() {
public static Singleton2 getInstance() {
return INSTANCE;
}
}
What is the benefit of Singleton2 over Singleton1 (if any)?
There is none, Java wise. Class initialization happens atomically, within locks. No thread will be able to see Singleton1#INSTANCE partially created.
At this point, use final to clarify (to developers) that this field should not change.
I'm fairly certain that the answer is none for performance. It could prevent a bug if someone were to try and modify the reference at some point during the maintenance cycle.
final is basically used for two purposes in java -
1) For immutability - If a field is final, then it can only be initialized only once. So, if INSTANCE is not final then you can reinitialize creating one more object but this can only be done as constructor is private. So, basically final can avoid any other bugs which can be introduced at later stage as mentioned by Elliott.
2) To ensure that object is properly constructed before publishing (it is in context of multithreading) but since we are instantiating the INSTANCE on class loading (eager loading). It will not cause any issues. It will be created long before it will be used.

how to use singleton pattern for sequence number creation in java

I have an Orders class and i need to have a singleton pattern to be able to create a sequence number for each order processed. How do i implement this?
My order class has an Order_ID, Customer_ID, Order_desc and Ordered_qty. There needs to be a sequence number created for each order processed using the singleton pattern.
This may be one of those X/Y problems, where you think Y is a solution to X, so you ask for help with Y, but perhaps there is a better solution.
Strictly speaking, to implement a singleton, all you need is a class whose only constructors are private, a static reference to an instance of the class as a class field, and a public getInstance method. Then create an instance method which returns the next number in line.
public class MySingleton {
private static MySingleton instance = new MySingleton();
private volatile int next = 0;
private MySingleton() {
// prevent external instantiation of a singleton.
}
public static MySingleton getInstance() {
return instance;
}
public synchronized int getNextSequence() {
return next++;
}
}
There are many flaws with this solution to your problem, some are just basic OOP design and some are more systemic:
A singleton that does not implement or extend any types is worthless. You could just use all static methods instead. Singletons are useful if you are writing a class that implements an interface and that interface is used by somebody else, but you only want a single instance as an implementation detail. This type of singleton is an attempt to make a global variable look like it is not a global variable.
This will not survive application restarts. If these sequences are being used to identify data that is stored externally or shared, you will end up repeating the same numbers when the application is restarted.
If you deploy multiple instances of the application who read and write to a common persistent storage, like a database, they will re-use the same numbers because the sequence is only tracked within the JVM.
Databases are already exceptionally good at this. Trying to re-invent it in the application tier seems.... inappropriate.
Although I agree #Elliott Frisch that the question itself sounds strange. However if you indeed have to generate IDs yourself here is the prototype that implements classic version of Singleton pattern.
public class IdGenerator {
private static IdGenerator instance;
private int id = 0;
private IdGenerator(){}
private static IdGenerator getInstance() {
synchronized(IdGenerator.class) {
if (instance == null) {
instance = new IdGenerator();
}
return instance;
}
}
public int nextId() {
return id++;
}
}
Please note that word "classic". There are a lot of possible improvements of Singleton pattern and there are hundreds of articles that explain them.
The key aspect is to use a single AtomicLong as the singleton. You may model it like this:
class Orders {
private static final AtomicLong NEXT_ID = new AtomicLong();
static Order newOrder(Customer customer, String description, int quantity) {
return new Order(orderId(), customer, description, quantity);
}
private static long orderId() {
return NEXT_ID.incrementAndGet();
}
}
class Order {
private final long orderId;
private final long customerId;
private final String description;
private final int quantity;
Order(long orderId, Customer customer, String description, int quantity) {
this.orderId = orderId;
this.quantity = quantity;
this.customerId = customer.getCustomerId();
this.description = description;
}
}
class Customer {
public long getCustomerId() {
throw new UnsupportedOperationException("not yet implemented");
}
}

Exposing instance constants with non-static public final variables

I never see this kind of constants declaration in any Java code around me...
So i'd like to know if you see any drawback of using non-static final constants.
For exemple, i've declared a Guava function as a public constant of a given MaintenanceMode instance. I think it's better because if i created a getDecoratorFunction() it would create a new function instance each time...
Or the get function could return the single instance function that is kept private in the class, but it hads useless code... When we declare constants at class level, we declare directly the constants being public, we do not put them private and provide a public getter to access them...
public class MaintenanceMode {
/**
* Provides a function to decorate a push service with the appropriate decorator
*/
public final Function<PushService,PushService> MAINTENANCE_DECORATION_FUNCTION = new Function<PushService,PushService>() {
#Override
public PushService apply(PushService serviceToDecorate) {
return new PushServiceMaintenanceDecorator(serviceToDecorate,MaintenanceMode.this);
}
};
private final EnumMaintenanceMode maintenanceMode;
private final long milliesBetweenMaintenances;
private final Optional<ExecutorService> executorService;
public EnumMaintenanceMode getMaintenanceMode() {
return maintenanceMode;
}
public long getMilliesBetweenMaintenances() {
return milliesBetweenMaintenances;
}
public Optional<ExecutorService> getExecutorService() {
return executorService;
}
private MaintenanceMode(EnumMaintenanceMode maintenanceMode, long milliesBetweenMaintenances, ExecutorService executorService) {
Preconditions.checkArgument(maintenanceMode != null);
Preconditions.checkArgument(milliesBetweenMaintenances >= 0);
this.maintenanceMode = maintenanceMode;
this.milliesBetweenMaintenances = milliesBetweenMaintenances;
this.executorService = Optional.fromNullable(executorService);
}
}
And i can access this variable with:
pushServiceRegistry.decoratePushServices(maintenanceMode.MAINTENANCE_DECORATION_FUNCTION);
I guess it could lead to strange behaviours if my maintenanceMode was mutable and accessed by multiple threads, but here it's not.
Do you see any drawback of using this kind of code?
Edit: I can have multiple instances of MaintenanceMode, and all instances should be able to provide a different constant function according to the MaintenanceMode state. So i can't use a static variable that would not access the MaintenanceMode state.
The point of a getter would be dynamic dispatch. If you have no need for it, using a public final field is perfectly fine. I even routinely write bean-like objects that have no getters, just public final fields.
By making a constant non-static, you are basically saying that the constant can only be accessed when you have an instance of that class. But it is public (in the case of MAINTENANCE_DECORATION_FUNCTION) and it is part of that class so why not make it static? The constant is, after all, a constant and it does not require an instance of that class to be used elsewhere. The variable maintenanceMode is fine as it is a private constant.

Categories

Resources