(Mis)usage of private constructor and static methods (Java)? - java

I am currently working on a project that needs to be refactored (it was not written by me and the original developer is not around). I see in that application that rather many classes have only private constructors and one or more static methods (getter/setter of the current class object). They also have non-static methods. I give you one example:
Class UndoManager that manages the actions taken on the application for performing undo/redo. It has only private constructors. When the application is loaded, UndoManager.setManager() is called. This method loads the undo history from a file or constructs a new one using a private constructor.
Later, every class can access this instance of UndoManager with syngronized static method .getManager().
In code:
public class UndoManager extends SimpleObservable<UndoManager> {
private static UndoManager instance;
private final Stack<Action> undoHistory;
private final Stack<Action> redoHistory;
public synchronized static void setManager(UndoManager undoManager) {
UndoManager instance = getManager();
instance.clear();
instance.undoHistory.addAll(undoManager.undoHistory);
instance.redoHistory.addAll(undoManager.redoHistory);
instance.notifyObservers(instance);
}
public synchronized static UndoManager getManager() {
if (instance == null)
instance = new UndoManager();
return instance;
}
private UndoManager() {
this.undoHistory = new Stack<Action>();
this.redoHistory = new Stack<Action>();
}
/.../
}
In this application multiple classes are used like this. They are not helper classes but classes that should have only one instance.
My question is:
is this kind of access good style? If not, how would you refactor the class and it's access?
I'm sorry if it is a duplicate, but I have searched in stackoverflow and google for a while but somehow I didn't find a satisfying answer. Thank you for any help.

This looks like a singleton pattern.
It is part of the great familly of designs patterns you might know them.
The point of this is to ensure that there is only one instance of this object used throughout your application. Indeed when you call getManager() it will return a new instance the first time and next times it will return the formerly created instance.

it's a design pattern that called Singleton. it's a lazy load and used for managers classes and service classes for example. they are for classes that you want an instance but only one instance of them.
there is usually a method to get the instance like your getManager method and a private constructor like you have

Related

Dagger 2 on Android. Different ways to store and access a #Singleton Component

This is the Nth question about how to store #Singleton scoped Dagger 2 Components whose lifetime should equal the application's lifetime.
In Android apps using Dagger 2 there is usually at least one Component which is #Singleton scoped and should last for all the application's lifetime: because of these requirements it is usually initialised and stored inside a custom Application class.
Since the instance of this Component must be reachable in all parts of our Application I've seen code like this:
1. Store the component in a public static variable inside the application class.
public class App extends Application {
public static AppComponent appComponent;
#Override
public void onCreate() {
super.onCreate();
appComponent = DaggerAppComponent.builder()
.appModule(new AppModule(this)).build();
}
}
This way it can be accessed anywhere else with:
App.appComponent.inject(this);
2. Store the component in a private variable inside the application instance and create a static accessor for it.
public class App extends Application {
private static AppComponent appComponent;
#Override
public void onCreate() {
super.onCreate();
appComponent = DaggerAppComponent.builder()
.appModule(new AppModule(this)).build();
}
public static AppComponent getAppComponent() {
return appComponent;
}
}
This way it can be accessed anywhere else with:
App.getAppComponent().inject(this);
3. Store the component in a private variable inside the application instance and create a non static accessor for it.
public class App extends Application {
private AppComponent appComponent;
#Override
public void onCreate() {
super.onCreate();
appComponent = DaggerAppComponent.builder()
.appModule(new AppModule(this)).build();
}
public AppComponent getAppComponent() {
return appComponent;
}
}
This way it can be accessed only from class instances which hold a reference to a Context:
// From within an Activity.
((App) getApplication()).getAppComponent().inject(this);
// From within a Fragment.
((App) getActivity().getApplication()).getAppComponent().inject(this);
// From within any other class which holds a reference to a Context.
((App) context.getApplicationContext()).getAppComponent().inject(this);
This last way makes it pretty much compulsory to pass a Context reference to any class willing to access the Component (even if that Context isn't needed by that class for any other purposes).
IMHO having to "manually inject" a Context instance only to access the injector itself sounds a bit counter intuitive.
On the other side many advise against using static variables but: why? If an object must stay in memory for the application's lifetime (which means for the whole lifetime of the JVM instance) what's the problem if it's stored in a static variable?
Others say that static stuff can't be mocked in tests and it's true, though I'm not sure I totally get this because it is the DI pattern which enables easy mocking/testing and not the injector itself, so why would we want to mock the injector itself?
What are the pros and cons of these alternatives? Are there any other possible alternatives besides the ones already mentioned here?
With 1 and 2 you are using static references. This is a good thread about why to avoid them
Why are static variables considered evil?
So the only option left is the 3rd. That is what I am using on my projects.
About if you should pass the context as argument or not, depends on the architecture of your project and how you designed the Dagger dependencies. Personally I don't have that problem because I am only injecting in Activities/Fragments. Can you give me an example where you need to pass the context to inject dependencies?
I use method #2. The main problem with method #1 is that you're exposing a mutable field. If your module doesn't require a Context to construct, you could make the field final. But as a matter of style, I still prefer not to expose fields.
You should normally avoid global state, especially in Android because of the complex and sometimes unintuitive lifecycles of components and the VM itself. But Application is the exception to this rule. Exactly one instance of it exists per VM, and its onCreate() method is called exactly once, before any other component is created. This makes it an acceptable place to create and store a static singleton.

How do I get different instances of Same singleton classes from 2 different jars in java [duplicate]

E.g I have class Singleton with static field instance:
public class Singleton {
private static Singleton instance;
// other code, construct, getters, no matter
}
I can load this class twice with two different classloaders. How could I avoid it? It is unsafe and dangerous.
Also, if I set instance to null, would it set to null for both classes?
Singleton singleton = Singleton.getInstance();
singleton = null;
If you want a true Singleton across classloaders, then you need a common parent to load the class in question, or you need to specify the classloader yourself.
Update: From the comment from #Pshemo below a fair bit of the content in the blog below might come directly from a JavaWorld Article. I've left the blog entry in as it may still help someone, but its worth knowing where the content originally came from.
Original:
There is a blog entry that gives you a way to do this" (although I havent tried it!), and it looks fairly reasonable
As requested below here a code snippet from my link above - I do suggest you visit the blog though for the full context:
private static Class getClass(String classname) throws ClassNotFoundException {
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
if(classLoader == null)
classLoader = Singleton.class.getClassLoader();
return (classLoader.loadClass(classname));
}
This is a hack misusing the fact that Properties extends Map, an old unfortunate design decision.
public final class JvmWideSingleton
{
private static final JvmWideSingleton INSTANCE;
static {
// There should be just one system class loader object in the whole JVM.
synchronized(ClassLoader.getSystemClassLoader()) {
Properties sysProps = System.getProperties();
// The key is a String, because the .class object would be different across classloaders.
JvmWideSingleton singleton = (JvmWideSingleton) sysProps.get(JvmWideSingleton.class.getName());
// Some other class loader loaded JvmWideSingleton earlier.
if (singleton != null) {
INSTANCE = singleton;
}
else {
// Otherwise this classloader is the first one, let's create a singleton.
// Make sure not to do any locking within this.
INSTANCE = new JvmWideSingleton();
System.getProperties().put(JvmWideSingleton.class.getName(), INSTANCE);
}
}
}
public static JvmWideSingleton getSingleton() {
return INSTANCE;
}
}
This could be made parametrized, but then the initialization would be lazy and go to getSingleton().
Properties is Hashtable-based, so it is thread safe (as per the documentation). So one could use props.computeIfAbsent(). But I like it this way more.
Also read here: Scope of the Java System Properties
I just wrote it and there is a chance there's something I overlooked that would prevent this from working.

Is it possible to limit method execution to a certain class?

I was wondering if it was possible to only allow a certain set of classes to execute a function.
I have a method: setPermission()
This method should only be called by certain classes throughout the project.
Some people suggested having the calling class pass in this, referencing the current object and ensuring it is an instanceof an allowed class. But any class could pass in an instance of an allowed class an so this seems to be an poor solution.
I also stumbled across Exception().getStackTrace()[1].getClassName(); however I am led to believe this is quite an expensive operation.
Is there a correct way to do this?
Use a marker interface (one that doesn't have any methods):
public interface Permissible {}
Then have the classes that are allowed to call your method implement it, then change the parameter type of your method to this interface:
public static void myMethodForObjectsThatHavePermission(Permissible obj) {
//
}
There's no way to enforce it that can't be worked around, but you could have most of your functionality on one class, setPermission() on a subclass, and make clients get an instance of your class via a factory method that is declared to return the parent class, but actually returns an instance of the subclass. That way, code that is supposed to call setPermission(), and knows about it, can do a downcast and call it, and all other users of the class won't even see it.
public class Service {
protected boolean permission = false;
protected Service() {
/* control creation */
}
public static Service getService() {
return new RealService();
}
public void doStuff() {
/* the public API side of the service */
}
}
public class RealService extends Service {
protected RealService() {
/* control creation */
}
public void setPermission(boolean permission) {
this.permission = permission;
}
}
A legitimate caller can do this:
public class Legitimate {
public void method() {
Service service = Service.getService();
RealService real = (RealService) service;
real.setPermission(true);
}
}
However, if all the legitimate callers can be put into the same package, and all the rest are outside the package, then package-private access (no access modifier) for setPermission() would be sufficient.
This doesn't prevent malicious callers from getting around the restriction, but it does avoid people calling setPermission without realizing they're not supposed to, because setPermission wouldn't show up in autocompletion (intellisense) in an IDE.
Sounds to me like you're looking for OSGi (en.wikipedia.org/wiki/OSGi). Third party developers should write bundles and with OSGi you can restrict capabilities of their bundles. Put your attention to: "Security The layer that handles the security aspects by limiting bundle functionality to pre-defined capabilities." Here is a thread discussing your case: Managing access to OSGI bundles

EventBus object's methods not working in java

I am trying to include EventBus in my application.
I followed http://tomaszdziurko.pl/2012/01/google-guava-eventbus-easy-elegant-publisher-subscriber-cases/ link.
I am getting compile errors:
I've added the guava-16.0.1.jar to the project.
But the register fucntion isn't working.
Any idea what am I missing here?
You're trying to call methods on members from the class, which is not possible. Those need to go inside a method (like a constructor or initializer).
Example code:
public class EventBusTest {
private final EventBus eventBus = new EventBus("test");
private final MultipleListener multiListener = new MultipleListener();
public void init() {
eventBus.register(multiListener);
}
}
Also, this question may be of use to help you understand Classes vs Objects

final static attribute change.. any idea or approach?

I have to maintain a code to add more flexibility to a final static variable in a class.
The variable is no more a global constant and may be changed.
The problem is that the class is in a common library and used in different projects.
Do you have an approach or a design pattern better than copying and pasting the class code from the common library to my specific application and refactoring it?
Example:
Commons project
Class CommonClass {
public final static var globalSomething = somethingGlobal;
public static method(){ //CommonClass.globalSomething is used here}
}
In my App (and other apps that reference commons) we can use the static attribute and also call the method:
---> var b = CommonClass.somethingGlobal;
---> var c = CommonClass.method() //we know that CommonClass.globalSomething is used here
Expectations:
Ability to change CommonClass.somethingGlobal in my app and take these changes in call CommonClass.method()
I can modify (add methods) in the common class but i have to keep the same initial behavior (not to break other project referencing common project)
If I got you right, you want to implement this as a parameter.
Looking at your example:
var c = CommonClass.method() //we know that CommonClass.globalSomething is used here
there is already something wrong with it. You shouldn't have to know that you have to set CommonClass.somethingGlobal correctly before calling the method. This way the client has to know the implementation, violating the principle of information hiding. If the value is required, introduce it as parameter:
Class CommonClass {
public static void method(var globalSomething){}
}
An alternative would be making both your variable and your method non-static and use a constructor:
Class CommonClass {
public var globalSomething = somethingGlobal;
public CommonClass(var globalSomething) {
this.globalSomething = globalSomething;
}
public void method(){}
}
PS: Your example code is not java. I corrected it partially in my answer.

Categories