Singleton Pattern: getInstance() vs Passing the singleton object? - java

What is the right / most popular way to utilize the Singleton Pattern.
Limit the no. of calls to getInstance(), preferably call it only once, and pass the object around to other classes during their instantiation?
class SingletonClass {
// Implementataion
}
class MainClass {
private SingletonClass singletonClassObject;
public MainClass() {
singletonClassObject = SingletonClass.getInstance();
new SomeClass(singletonClassObject).doSomething();
new SomeOtherClass(singletonClassObject).doSomethingElse();
}
}
class SomeClass {
private SingletonClass singletonClassObject;
public SomeClass(SingletonClass singletonClassObject) {
this.singletonClassObject = singletonClassObject;
}
public void doSomething() {
System.out.println(singletonClassObject.getStuff());
}
}
class SomeOtherClass {
private SingletonClass singletonClassObject;
public SomeOtherClass(SingletonClass singletonClassObject) {
this.singletonClassObject = singletonClassObject;
}
public void doSomethingElse() {
System.out.println(singletonClassObject.getStuff());
}
}
Don't pass the singleton object around. Rather call get the object reference in each class and save the reference as an instance variable and use it wherever required.
class SingletonClass {
// Implementataion
}
class MainClass {
public MainClass() {
new SomeClass().doSomething();
new SomeOtherClass().doSomethingElse();
}
}
class SomeClass {
private SingletonClass singletonClassObject;
public SomeClass() {
singletonClassObject = SingletonClass.getInstance();
}
public void doSomething() {
System.out.println(singletonClassObject.getStuff());
}
}
class SomeOtherClass {
private SingletonClass singletonClassObject;
public SomeOtherClass() {
singletonClassObject = SingletonClass.getInstance();
}
public void doSomethingElse() {
System.out.println(singletonClassObject.getStuff());
}
}
Don't even save the reference as an instance variable, rather use SingletonClass.getInstance() everywhere you need the object.
class SingletonClass {
// Implementataion
}
class MainClass {
public MainClass() {
new SomeClass().doSomething();
new SomeOtherClass().doSomethingElse();
}
}
class SomeClass {
public SomeClass() {
}
public void doSomething() {
System.out.println(SingletonClass.getInstance().getStuff());
}
}
class SomeOtherClass {
public SomeOtherClass() {
}
public void doSomethingElse() {
System.out.println(SingletonClass.getInstance().getStuff());
}
}
How do these approaches compare with each other w.r.t. better design, testability etc? Which is better and why?

If we assume for a moment that SingletonClass is not a singleton and we do not get an instance by calling static method we face another problem, how to link these classes together. This problem is solved by Dependency Injection and this concept is well described here:
Inversion of Control Containers and the Dependency Injection pattern
Unit Testing 101: Inversion Of Control
After reading above it should be easy to choose option .1 where all classes get in constructor references to required dependencies. You can even create an interface for a behaviour you need and implement it in SingletonClass. Now you see, that a fact that class implements Singleton pattern does not make it special and we should inject them like other classes. All benefits from using DI you can apply to your class.
Just compare it with .3 and you need to write a test where you need mock something. It would be more unpleasant task then in case of .1.

Look at it this way: you're questioning the compiler's ability to recognize that a static final reference can be compiled as an inline reference.
I would guess the compiler converts the getInstance() to an inline reference. I would be less confident that the compiler would recognize that you're intentionally creating extra work for yourself when you pass a reference by value, and that it would create an extra reference on the stack when you passed it around.
My guess is that getInstance() would be more efficient.

Related

Get an already existing object from another class

Im very new to programming and want to know if I can somehow get the object from a class where I already used new MyClass(); to use it in another class and that I don't need to use new MyClass(); again. Hope you get the point.
Some very simple example:
class MyFirstClass
{
Something st = new Something();
}
class Something()
{
// some code
}
class MySecondClass
{
// This is where I want to use the object from class Something()
// like
getObjectFromClass()
}
You can use Singleton pattern to achieve this
This is kickoff example of such object. It has a private constructor and public class method getInstance:
static methods, which have the static modifier in their declarations,
should be invoked with the class name, without the need for creating
an instance of the class
When we make a call to getInstance it checks if an object has been created already and will return an instance of already created objected, if it wasn't created it will create a new object and return it.
public class SingletonObject {
private static int instantiationCounter = 0; //we use this class variable to count how many times this object was instantiated
private static volatile SingletonObject instance;
private SingletonObject() {
instantiationCounter++;
}
public static SingletonObject getInstance() {
if (instance == null ) {
instance = new SingletonObject();
}
return instance;
}
public int getInstantiationCounter(){
return instantiationCounter;
}
}
To check how does this work you can use the following code:
public static void main(String[] args) {
SingletonObject object = SingletonObject.getInstance();
System.out.println("Object was instantiated: " + object.getInstantiationCounter() + " times.");
object = SingletonObject.getInstance();
System.out.println("Object was instantiated: " + object.getInstantiationCounter() + " times.");
object = SingletonObject.getInstance();
System.out.println("Object was instantiated: " + object.getInstantiationCounter() + " times.");
}
Since you have just started coding won't give you a term like reflection and all.. here is one of the simple way is have a public getter() method.
Consider this simple example
class Something {
private int a=10;
public int getA() {
return a;
}
}
Here is the First which has a public method which return the object that i created in this class for the Something Class
class MyFirstClass {
private Something st;
public MyFirstClass() {
this.st = new Something();
}
public Something getSt() {
return st;
}
}
Accessing it from another Class
class MySecondClass {
public static void main(String...strings ){
MyFirstClass my =new MyFirstClass();
System.out.println(my.getSt().getA());
}
}
Output: 10
If You wan't to verify
Inject this function in MyFirstClass
public void printHashcode(){
System.out.println(st);
}
and then print the hash codes from both methods in MySecondClass
class MySecondClass {
public static void main(String...strings ){
MyFirstClass my =new MyFirstClass();
System.out.println(my.getSt());
my.printHashcode();
}
}
You will see that indeed you are using the Object created in MyFirstClass in MySecondClass.
Because this will give you same hashcode output.
Output On my machine.
Something#2677622b
Something#2677622b
Instead of using the Singleton pattern, a better pattern to use is dependency injection. Essentially, you instantiate the class you want to share, and pass it in the constructor of every class that needs it.
public class MainClass {
public static void main(String[] args) {
SharedClass sharedClass = new SharedClass();
ClassA classA = new ClassA(sharedClass);
ClassB classB = new ClassB(sharedClass);
}
}
public class ClassA {
private SharedClass sharedClass;
public ClassA(SharedClass sharedClass) {
this.sharedClass = sharedClass;
}
}
public class ClassB {
private SharedClass sharedClass;
public ClassB(SharedClass sharedClass) {
this.sharedClass = sharedClass;
}
}
Singleton pattern lets you have single instance which is 'globally' accessible by other classes. This pattern will 'guarantee' that you have only one instance in memory. There are exceptions to one instance benefit, such as when deserializaing from file unless care is taken and readResolve is implemented.
Note that class Something right now has no state(fields), only behavior so it is safe to share between multiple threads. If Something had state, you would need to provide some kind of synchronization mechanism in multi thread environment.
Given such stateless Singleton, it would be better to replace it with class that contains only static methods. That is, unless you are implementing pattern such as Strategy which requires interface implementation, then it would be good idea to cache instance like bellow with Singleton pattern.
You should rework your Something class like this to achieve singleton:
public class Something {
private static final Something INSTANCE = new Something ();
private Something () {
// exists to defeat instantiation
}
public Something getInstance() {
return INSTANCE;
}
public void service() {
//...
}
public void anotherService() {
//..
}
}
If FirstClass and SecondClass are somehow related, you can extract that common object you're using to a super class, and that's the only scope in which you're planning to use this object.
public class SuperClass{
Something st = new Something();
public Something getObjectFromClass(){
return st;
}
}
public class MyFirstClass extends SuperClass{
getObjectFromClass();
}
public class MySecondClass extends SuperClass{
getObjectFromClass();
}
Otherwise, if you plan to use that instance somewhere else you should use a
Singleton object. The easiest way of doing this is:
enum Singleton
{
INSTANCE;
private final Something obj;
Singleton()
{
obj = new Something();
}
public Something getObject()
{
return obj;
}
}
You use it:
Singleton.INSTANCE.getObject();
Okay firstly you can use inheritance e.g.
class MyFirstClass
{
Something st = new Something();
}
class Something()
{
// some code
}
class MySecondClass extends myFirstClass
{
// This is where I want to use the object from class Something()
// like
MySecondClass obj = new MySecondClass();
obj.method(); //Method from myfirstclass accessible from second class object
}
Or if you dont want any objects and just the method you can implement interfaces e.g.
public interface MyFirstClass
{
//example method
public abstract void saying(); //no body required
Something st = new Something();
}
class Something()
{
// some code
}
class MySecondClass implements MyFirstClass //Have to implement methods
{
public void saying(){ //Method implemented from firstClass no obj
System.out.println("Hello World");
}
getObjectFromClass()
}

Java send instanceof as paramater

This might be a stupid question but I gotta know if there is a way to send the instance of a object to a method?
Like this:
public class TestClass
{
public TestClass()
{
//Initialize
}
}
public class AnotherClass
{
Instance!? mInstance;
public AnotherClass(Instance!? instance)
{
mInstance = instance;
}
public boolean isInstanceOfTestClass()
{
return mInstance == TestClass;
}
}
public class Main
{
public static void main(String[] args)
{
AnotherClass a = new AnotherClass(TestClass);
if(a.isInstanceOfTestClass)
System.out.println("lala");
}
}
(Tried to make it wrapped as codeblock)
There's no such thing as an "instance of an object". An object is an instance of a class - so "instance" and "object" refer to the same thing.
You can use the instanceof operator to test if an arbitrary object is an instance of a particular class:
if (a instanceof AnotherClass) {
// ...
}
There's also the class java.lang.Class, which represents the class of an object. You can get it by calling getClass() on an object:
Class<?> cls = a.getClass();
See the API documentation of java.lang.Class.
Well you can use Class.isAssignableFrom and construct with an instance of Class where T is the class you want to test for.
But if you are bothered about about enforcing typing and making non-type specific classes I suggest you read up on generics.

How to refactor a class hierarchy of singletons where each class has a getInstance() method?

I have inherited a particular class hierarchy of singletons whose declarations are summarized below (there are more implementations -- I'm just showing the minimal set to demonstrate the problem). It smells to high heaven to me, foremost because singletons are being inherited from, as well as the way instance in the base class has its value overwritten in the static initializers of the subclasses.
If all the implementations were in the foo.common parent package I would consider just dropping the instance member and getInstance() methods from them, making the classes and their constructors package-local, and having some public factory class in foo.common create a single instance of each, hold onto that single instance of each internally (partitioned by whether it was an implementation of IReadOnly or IReadWrite) and provide a couple of public lookup methods where based on some enum it would return the asked-for implementation as the interface type.
But implementations can be outside of foo.common and foo.common isn't allowed to depend on such "more specific" packages, since foo.common is intended for stuff common to a bunch of apps. So something that simple can't be done. What then?
First interface:
package foo.common.config;
public interface IReadOnly
{
void load();
String getVal(String key);
}
Second interface:
package foo.common.config;
public interface IReadWrite extends IReadOnly
{
void save();
void setVal(String key, String value);
}
First implementation:
package foo.common.config;
public class ReadOnlyImpl implements IReadOnly
{
protected static IReadOnly instance;
static {
instance = new ReadOnlyImpl();
}
public static IReadOnly getInstance() {
return instance;
}
protected ReadOnlyImpl() {}
// implement methods in IReadOnly
}
Second implementation
package foo.common.config;
public class ReadWriteImpl extends ReadOnlyImpl implements IReadWrite
{
static {
instance = new ReadWriteImpl();
}
public static IReadWrite getInstance() {
return (IReadWrite) instance;
}
protected ReadWriteImpl() {
super();
}
// Implement methods in IReadWrite
}
Third implementation:
// While things in this package can depend
// on things in foo.common, nothing in
// foo.common is allowed to depend on this package.
package foo.apps.someapp;
public class MoreSpecificReadWriteImpl extends ReadWriteImpl
{
static {
instance = new MoreSpecificReadWriteImpl();
}
public static IReadWrite getInstance() {
return (IReadWrite) instance;
}
protected MoreSpecificReadWrite() {
super();
}
// Override superclass methods to do something specific
}
Putting package foo.apps.someapp aside, the design of the package foo.common.config is wrong.
IReadOnly o1=ReadOnlyImpl.getInstance(); // ok, returns ReadOnlyImpl
...
ReadWrite o2=ReadWriteImpl.getInstance(); // ok, returns ReadWriteImpl
...
IReadOnly o3=ReadOnlyImpl.getInstance(); // bad, returns ReadWriteImpl, the same as o2.
The reason is that all classes use the same static variable ReadOnlyImpl.instance. I would use separate variable in all classes, including MoreSpecificReadWriteImpl. If this would not fit, then think of using Spring container or similar framework.

Design Patterns question

I have a following problem I want to solve ellegantly:
public interface IMyclass
{
}
public class A
{
public void Init(IMyclass class){?}
public IMyclass CreateMyClass(){?}
}
At the start of the system I want to define dynamic type of IMyClass by using Init() and during the run of the system i would like to create new instances of the type I defined at init.
Notes:
1. IMyclass must be interface
2. The dynamic type of IMyclass known only at init (i have no constructor after :) )
3. I could do it using a reflection or definition method clone at IMyclass is there any better solutions?
Thank you.
You could pass a provider into class A
public class A
{
IMyClassProvider _provider;
public void Init(IMyClassProvider provider)
{
_provider = provider;
}
public IMyclass CreateMyClass()
{
return _provider.Create();
}
}
Or maybe with a constructor delegate
public class A
{
Func<IMyclass> _ctor;
public void Init(Func<IMyclass> ctor)
{
_ctor = ctor;
}
public IMyclass CreateMyClass()
{
return _ctor();
}
}
Note that both of these examples will blow up if Init has not been called before CreateMyClass, you would need some checking or better is doing your init in the constructor.
Have I understood the question correctly?
This is a kind of dependency injection, you should read:
http://en.wikipedia.org/wiki/Dependency_injection
http://www.martinfowler.com/articles/injection.html#FormsOfDependencyInjection
Basically, you have a class A that is populated with factories (or providers) at initialization. Then you use A instead of calling new.
A quick example:
interface Provider<V> {
V instance(Object... args);
}
class Dispatch {
// you can make a singleton out of this class
Map<Class, Provider> map;
<T> void register(Class<T> cl, Provider<? extends T> p) {
// you can also bind to superclasses of cl
map.put(cl, p);
}
<T, I extends T> void register(Class<T> cl, final Class<I> impl) {
register(cl, new Provider<I>() {
I instance(Object... args) {
// this class should be refactored and put in a separate file
// a constructor with arguments could be found based on types of args values
// moreover, exceptions should be handled
return impl.newInstace();
}
});
}
<T> T instance(Class<T> cl, Object... args) {
return map.get(cl).instance(args);
}
}
// usage
interface MyIf { ... }
class MyIfImpl implements MyIf { ... }
Dispatch d = new Dispatch();
d.register(MyIf.class, new Provider<MyIf>() {
MyIf instance(Object... args) {
return new MyIfImpl();
}
});
// or just
d.register(MyIf.class, MyIfImpl.class);
MyIf i = d.instance(MyIf.class);
Edit:
added register(Class, Class)
If you just want to instantiate the same class in CreateMyClass() without further configuration you can use reflection.
public class A
{
private Class prototype;
public void Init(IMyClass object) {
this.prototype = object.getClass();
}
public IMyClass CreateMyClass() {
return prototype.newInstance();
}
}
I suspect you want more than this, and if so you'll need to explain how you want to use this. You may be looking for the Builder or Factory patterns.
You'll need Reflection at some point due to visibility. If you can accept Reflection once up-front and not have to use it again, that would probably be ideal, yes?
You could put a getInstance() method on a hidden interface (located in the same package as IMyClass, MyClassImpl, and A, but not ClientOfA), and then pass a prototype of MyClassImpl to A.init().
// -- You wish you would have thought of the word prototypeable! ...maybe?
interface IMyClassPrototypeable extends IMyClass
{
public IMyClass getInstance();
}
class MyClassImpl implements IMyClassPrototypeable // -- and IMyClass by extension.
{
// -- Still not visible outside this package.
public IMyClass getInstance()
{
return new MyClassImpl();
}
}
class A
{
private IMyClassPrototypeable prototype;
// -- This method is package-private.
void init( IMyClassPrototypeable prototype )
{
this.prototype = prototype;
}
public IMyClass createMyClass()
{
return prototype.getInstance();
}
}
This solution would require Reflection to create the prototype instance of MyClassImpl, which could be done via Spring (or some other form of dependency injection). It uses the Prototype pattern, the Factory-method pattern, and readily supports the Singleton/Pool pattern, but remember that more design patterns used is not always better. In fact, it can make the design (and code) more complex and more difficult for a beginner to understand.
For the record, the only reason I would even think about advocating this solution is because it takes the reflection hit once, up front, rather than every time createMyClass() is called, which the original poster indicated he/she would be doing frequently.

extends of the class with private constructor

Suppose we have the following code:
class Test {
private Test() {
System.out.println("test");
}
}
public class One extends Test {
One() {
System.out.println("One");
}
public static void main(String args[]) {
new One();
}
}
When we create an object One, that was originally called the parent class constructor Test(). but as Test() was private - we get an error.
How much is a good example and a way out of this situation?
There is no way out. You have to create an available (protected, public or default) super constructor to be able to extend test.
This kind of notation is usually used in utility classes or singletons, where you don't want the user to create himself an instance of your class, either by extending it and instanciating the subclass, or by simply calling a constructor of your class.
When you have a class with only private constructors, you can also change the class to final because it can't be extended at all.
Another solution would be having a method in test which create instances of test and delegate every method call from One to a test instance. This way you don't have to extend test.
class Test {
private Test() {
System.out.println("test");
}
public static Test getInstance(){
return new Test();
}
public void methodA(){
//Some kind of implementation
}
}
public class One {
private final Test test;
One() {
System.out.println("One");
test = Test.getInstance();
}
public void methodA(){
test.methodA();
}
public static void main(String args[]) {
new One();
}
}
Make the constructor of test non-private or move One into test.
BTW, your sample code contains a few issues:
classes should be named title case (Test instead of test)
I'd suggest to make the One's constructor private unless it is called from a different class in the same package
Actually, I found there is a way out. Like this:
class Base {
private Base() {
}
public void fn() {
System.out.println("Base");
}
public static class Child extends Base {
public void fn() {
System.out.println("Child");
}
}
public static Base getChild() {
return new Child();
}
}
Now, you can use getChild() to get instance of the extended class.

Categories

Resources