How to implement a subclassable Singleton in Java - java

I am looking for a way to implement an abstract class (or effectively abstract) that enforces only one instance of each subclass.
I am fairly sure this would be pretty simple to implement with a Factory but I would be interested to know if it can be done without knowing all subclass types, i.e a generic singleton enforcer class.
Right now I am mostly just playing around with the idea for something like this, So I am not looking for feedback that questions the design choice here.
The language I am working in is Java, but right now I am not necessarily worried about implementation details, Unless it is not possible in Java, then, of course, provide evidence that it is not possible.

I'm wondering what it is you are trying to do. A couple of possibilities spring to mind and knowing where this is heading might help.
Option 1
So you could try to use an enum type as your abstract base class. Each enumeration constant is then guaranteed by the language to be a singleton. The enum can have abstract methods which the constants implement. This will work but compilation unit an get very big and hard to navigate if you have a lot of implementing constants and a lot of abstract methods to implement. You could of course delegate some of the work to helper classes if it starts to get out of hand.
Option 2
You could do is get the base class constructor to check it's actual type and store it in a static HashSet (or similar). If an entry already exists then you have two instances of the same singleton. Something like
public abstract class BaseClass {
private static HashSet<Class<?>> instances = new HashSet<>();
protected BaseClass() {
checkInstances();
}
private synchronized void checkInstances() {
boolean duplicate = instances.add(getClass());
if (duplicate) {
throw new RuntimeException("Duplicate class " + getClass().getName());
}
}
}
The disadvantage of this is that the error occurs at runtime and the code isn't especially pretty and as you can see you may need to consider synchronization of the set
Option 3
Your final option is simply not to ask the base class to enforce this restriction. It should probably the job of the derived classes to decided if they are singletons or not. A private constructor in the derived class is the easiest way to do that.
Conclusion
Personally I'd implement either option 1 or option 3 as you won't get run-time failures.

First, a generic singleton doesn't make sense.
A parent class should not be responsible of retrieving and managing instances of its subclasses.
It creates a strong coupling in both ways (parent->child and child->parent).
Second, as shmosel says, subclassing a singleton (without special artifact) is not possible.
The key of the singleton pattern is the lack of ability to instantiate the class outside the singleton class, so no public constructor has to be provided.
In these conditions, how subclass the singleton class ?
To allow subclassing a singleton class, you must have a public constructor while ensuring that you have no more than one instance of the class.
Inversion of control containers such as Spring may do that (It is an example of special artifact).
As a side note, I don't consider access modifier tweaking such as the package-private modifier that could allow to subclass a singleton but the limitation of it is that the singleton would be a singleton only outside the package.

I wanted to say, that singletons are bad. But found this problem interesting, So I created what you want.
Here is the code
public static abstract class SingletonBase {
private static HashSet<SingletonBase> instances = new HashSet<>();
{
for (SingletonBase sb : instances) {
if (sb.getClass() == this.getClass()) throw new RuntimeException("there is already 1 instance");
}
}
public static <E> E getInstance(Class<E> clazz) {
if (!SingletonBase.class.isAssignableFrom(clazz)) {
throw new RuntimeException();
}
for (SingletonBase sb : instances) {
if (sb.getClass() == clazz) return (E) sb;
}
try {
return clazz.newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return null;
}
private SingletonBase() {
instances.add(this);
}
}
static class SingletonTest extends SingletonBase{
}
static class SecondSingletonTest extends SingletonBase{
}
public static void main(String[] args) {
for(int i=0;i<=10;i++)
System.out.println( SingletonBase.getInstance(SingletonTest.class));
for(int i=0;i<=10;i++)
System.out.println( SingletonBase.getInstance(SecondSingletonTest.class));
//throws exception, because we try to create second instance here
new SingletonTest();
}
There are some problems with approach of creating generic class which are solved here:
first, you cannot create more than one instance, so base class has to keep track of all instances, and when you try to create another one using new, it will throw exception. Second, you need to get instance for a specific class. If you dont want to create instance like this:
SingletonBase.getInstance(SecondSingletonTest.class)
You can create subclasses like this:
static class SingletonTest extends SingletonBase{
public static SingletonTest getInstance(){
return getInstance(SingletonTest.class);
}
}
There was also suggested to use ENUM approach, it is easy to implement, but breakes open closed principle from SOLID

Related

Calling extended's class method from parent class with extended class keeping instances of parent's variables

I'm implementing a visitor pattern for a particular domain, where I have some BaseVisitor, ie:
public class BaseVisitor {
someC someInstance;
visitA(...) {
...
}
visitB(...) {
...
}
}
and a class that changes one particular functionality, ExtendedVisitor, ie:
public class ExtendedVisitor extends BaseVisitor {
visitA(...) {
...
}
}
This ExtendedVisitor has a different implementation of visitA.
What I want to do is that when I'm in visitB of BaseVisitor, in special case I want to use the method of the ExtendedVisitor (visitA) as opposed to the regular visitA of the BaseVisitor itself. This works fine, ie.:
visitB(...) {
if (...)
new ExtendedVisitor().visitA();
else
visitA();
}
Now obviously, in the BaseVisitor there are many visit methods, and so the visitA of ExtendedVisitor will call them (ie. the original implementation of those methods - in BaseVisitor). The problem is that at this point I lost the instance of someInstance (ie. it is null). Is there a way for the two classes to share the variables? Ie. let the child use parent's variables?
Since you are calling to new ExtendedVisitor() you are creating a new instance of that class and of course someInstance will be null. You could create a constructor like
public ExtendedVisitor(someC someInstance ){
this.someInstance = someInstance
}
But it doesn't sound a great idea...
With your design you are forcing your parent class to know the functionality of its children classes. I see a coupling issue here. Probably you should rethink your code and use inheritance and polimorfism in a better way.

Dynamically Casting class and calling appropriate methods

I am writing a utility which uses some classes defined in a 3rd party library which i do not control.
I would like the to know what would be a good way to handle situations like the one described below :
3rd party library has a base abstract class 'Food' which is extended by 'Appetizer','Entree',"Beverage' and 'Dessert'. (all part of 3rd Party Library)
I am writing a 'WaiterUtility' which has methods to serve each type of food.
I want to avoid an endless chain of instanceof checks .
`
Class WaiterUtility{
public serveItems(Food[] items)
{
for(Food aFood : items){
//how do i call the sub-class specific methods i wrote below?
}
}
private void serve(Appetizer aFood){//somecode}
private void serve(Entree aFood){//somecode}
private void serve(Beverage aFood){//somecode}
private void serve(Dessert aFood){//somecode}
}
`
If at all possible, I would implore you NOT to use reflection as TBotV63 does in his answer (he even says to avoid it). From the Oracle documentation:
If it is possible to perform an operation without using reflection, then it is preferable to avoid using it.
So, obviously we're inclined to say that all Foods can be served, and that any Waiter can serve any kind of Food. Ideally a good API would therefore expose methods that would be sufficient for a serve(Food) method to do the job without knowledge of what kind of food it is. It seems like your question implies that this is not the case, and therefore something more needs to be done.
If the 3rd party library accepts community input then you should try to open an issue or a pull request to add the functionality.
Obviously that's not always possible, so the next best thing to do would be to create an interface (something like Serveable) which defines the methods you would need, and then subclass the different types of food while implementing that interface. Then you would have Waiter.serve(Serveable).
This is more work than reflection or many uses of instanceof, but it is better OO design.
Why reflection is bad
The documentation for reflection points out 3 drawbacks of reflection
exposure of internals
performance
security
While you might not care about 2 or 3, 1 is especially bad.
... use of reflection can ... render code dysfunctional and may destroy portability. Reflective code breaks abstractions and therefore may change behavior with upgrades of the platform.
Why instanceof is bad (in this case)
serveItems(Food[]) implies to the caller that if you pass it several Food items, it will serve each of them. However this is not really the case. We can only serve certain sub-classes of Food, and we will have run-time errors if we try anything else. Java is a nice typesafe language, we like compile-time errors much more than run-time errors.
Another downside is that additional code needs to be added to Waiter every time a new sub-class of Food is added or changed. This becomes a cross-cutting concern and makes the code unscalable from a development perspective.
These are by no means the only downsides/issues, just a couple examples.
You can try following code:
Class WaiterUtility{
private Map<Class<? extends Food>, Waiter> waiters = new HashMap<>();
WaiterUtility() {
waiters.put(Appetizer.class, new AppetizerWaiter());
waiters.put(Entree.class, new EntreeWaiter());
waiters.put(Beverage.class, new BeverageWaiter());
waiters.put(Dessert.class, new DessertWaiter());
}
public serveItems(Food[] items)
{
for(Food aFood : items){
waiter.get(aFood.getClass()).serve(aFood);
}
}
private static abstract interface Waiter {
private void serve(Food aFood);
}
private static class AppetizerWaiter implements Waiter {
private void serve(Food aFood){
Appetizer appetizer = (Appetizer) aFood;
//somecode
}
}
private static class EntreeWaiter implements Waiter {
private void serve(Food aFood){//somecode}
}
private static class BeverageWaiter implements Waiter {
private void serve(Food aFood){//somecode}
}
private static class DessertWaiter implements Waiter {
private void serve(Food aFood){//somecode}
}
}
Try something similar to the following:
public serveItems(Food[] items)
{
for(Food aFood : items){
Class<?> foodClass = aFood.getClass(); // Get the food's class
Method serve = WaiterUtility.class.getMethod("serve", foodClass); // Get the method by name and argument types
try {
serve.invoke(this, aFood);
} catch (IllegalArgumentException e) { // Should never occur, we're matching it up.
} catch (IllegalAccessException e) { // Shouldn't occur, we're in the same class.
} catch (InvocationTargetException e) {
// Handle errors possibly thrown by the serve method.
}
}
Haven't tested this tho.
Note that you should however avoid this, it's terrible design.

How to Prevent instantiation of concrete classes?

Lets say I have a Record Interface and I can have N number of its concrete implementation classes eg. PropertyRecords,LoanRecords etc.How do I ensure there is no object of these N classes is created by client using new keyword?
Its quite easy if I have a single subclass;I can Make all the constructors package private;so that I can write a Factory class in the same package which will have a method which will be responsible for creating instances.But how to create a virtual Factory able to create several implementations of a single interface or abstract class.
Hope i am able to put myself correctly.Please ask if any clarification needed.
Thank you.
Not sure why you would want this, but your Factory class can use reflection to create instances like this:
public class RecordFactory {
public Record newInstance(Class<? extends Record> klass, Object... args) {
Constructor[] ctors = klass.getDeclaredConstructors();
// find the right constructor here..
return ctor.newInstance(args);
}
}
Then your clients can create instances like:
RecordFactory.newInstance(Loan.class, ...);
I'm not entirely sure I understand what you're trying to achieve (comment on this is not), but here are my thoughts:
Sounds like what you really want is to implement the Flyweight design pattern (http://en.wikipedia.org/wiki/Flyweight_pattern).
If you really want to implement this as you describe it (again, under the assumption that I understood correctly), the following should work:
public class Record {
private static final int MAX_INSTANCES = 20;
private static volatile int instanceCounter = 0;
private Record() {
if (instanceCounter >= MAX_INSTANCES)
throw new RuntimeException("max instances exceeded");
instanceCounter ++;
}
}

Preventing subclasses from adding methods

This might seem like an odd thing to want, but is there a way in Java to stop subclasses from adding new methods (including constructors) whilst still allowing subclasses to override methods?
The actual situation is where we have an abstract class with some abstract methods and a constructor
abstract class A {
abstract A doX();
abstract boolean isY();
public A(String s){ ... };
}
and we want all concrete subclasses of this class to only override these methods and constructor.
This is about enforcing a certain style in our code i.e. stopping other people working on the code from adding things. We could just tell them not to, but that rarely works, so we wondered if there was a programmatic way of achieving this.
Obviously the class cannot be final. Efficiency isn't paramount - cleaner code is more important.
Update - dynamic approach
As has been pointed out in the answers, there is no way to do this statically as the only way to prevent subclasses being created is using final, which won't work. But I could use a dynamic approach so my current solution is to add this aspect to the project (which already uses AspectJ).
public aspect WatchA{
before() : execute(* A.*()) || execute(* A.*(..)) {
String methodCalled = joinPoint.getSignature().getName();
Class<?> c = Class.forName(args[0])
Method[] allMethods = c.getDeclaredMethods();
boolean found = false;
for(Method m : allMethods)
found |= m.getName().equals(methodCalled);
if(!found)
throw new RuntimeException("Do not add method "+methodCalled+" to A");
}
}
Which will cause their tests to fail if they use any of these new methods.
You cannot do that. Only if classes are final can you ensure that no subclass can be created.
You can also make methods final (even in abstract classes) so that overriding them is forbidden.
Your best bet is to create an interface, with all methods you want visible, and force all users of your API to access the objects via this interface. This way, even if implementations add their own stuff, said stuff won't be visible.
One solution for this is to implement a factory to return the concrete classes; for "added security", you could put all implementations in the same package as this factory and make constructors package local (but this is often not practical):
public final class MyFactory
{
// ....
public MyInterface getConcrete()
{
return new MyInterfaceImpl();
}
// etc etc -- getStones(), getTar(), getFeathers() and so on
}
Note that builders can also be used for that.
If you really wan't to do this.. one way would be to programatically check in the abstract class constructor that the methods defined in the class are those that are allowed.
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
public abstract class Base {
private static final Set<String> allowedMethodNames = new HashSet<>(Arrays.asList("doThis", "wait", "wait", "wait", "equals", "toString", "hashCode", "getClass", "notify", "notifyAll"));
public Base() {
Set<String> allMethods = new HashSet<>();
for (Method aMethod : getClass().getMethods()) {
allMethods.add(aMethod.getName());
}
if (!allowedMethodNames.equals(allMethods)) {
allMethods.removeAll(allowedMethodNames);
throw new IllegalStateException("Following methods not allowed <" + allMethods + ">");
}
}
public abstract void doThis();
}
public class Disallowed extends Base {
#Override
public void doThis() {
System.out.println("dooooooo");
}
public void doSomethingElse() {
System.out.println("not allowed");
}
public static void main(String[] args) {
new Allowed().doThis();
new Disallowed();
}
}
public class Allowed extends Base {
#Override
public void doThis() {
System.out.println("doing this");
}
}
When someone is trying create an instance of 'Disallowed' it would fail. However 'new Allowed().doThis()' will work fine.
A more graceful way to do this would be to introduce a custom annotation + annotation processor and do the same check during the compilation time.
There is no such way.
Why would you want to enforce such a coding style?
If you really must enforce such a style you could create a "rule enforcer" which checks your classpath and compares the methods of your abstract parent classes with their sub classes.
It is Java which means flexibility. So java gives you more convinient in using the abstract methods and overriding them from your subclasses. Also one should have an idea of adding new methods to these subclasses. Even java can't change this. If it does then the whole Java community crash. It is impossible that you can prevent from adding methods to their subclasses. Only you can stop them extending your classes and overridding your methods.

How do I reduce delegation boilerplate?

I have a class that implements an interface. There's another class that implements this interface, too, and an instance of this second class backs my class's implementation.
For many of the methods specified by the interface, my class simply forwards them straight to the second class.
public class MyClass implements MyInterface
{
private OtherClass otherClassInstance; // Also implements MyInterface.
// ...
void foo() { otherClassInstance.foo(); }
void bar() { otherClassInstance.bar(); }
void baz() { otherClassInstance.baz(); }
// ...
}
Simply deriving my class from the second class would eliminate all of this, but it doesn't make sense because the two classes are unrelated to each other (besides implementing a common interface). They represent different things - it just so happens that a lot of my class's implementation copies that of the other class. In other words, my class is implemented atop the second class, but it is not itself a subset of the second class. As we know, inheritance is meant to express an "is-a" relationship, not to share implementation, so it's inappropriate in this case.
This portion of a talk by Joshua Bloch illustrates the situation well.
I know that Java doesn't have any language support for delegation. However, is there at least some way to clean up my class's implementation so it isn't so redundant?
An answer which is not really an answer to your actual question:
I'd say, live with the boilerplate. Let IDE generate it for you. Example: in Netbeans, add the private ArrayList field, set cursor to where you'd want the methods to appear, hit alt-insert, select "Generate Delegate Method...", click the methods you want to create a delegate for in the dialog opens, submit, go through the generated methods and make them do the right thing, you're done.
It is a bit ugly, but it is still preferable to starting to mess with reflection, when you are dealing with just one class, like it sounds. Your class is probably the kind of class, which you will complete and fully test, and then hopefully never touch again. Reflection creates runtime cost which does not go away. Suffering the auto-generated boilerplate in the source file is probably preferable in this case.
First way to use http://java.sun.com/javase/6/docs/api/java/lang/reflect/Proxy.html see tutorial http://docs.oracle.com/javase/1.4.2/docs/guide/reflection/proxy.html
Second way using AOP you can create dispatcher that intercept all invocation of specific class
For both ways you need to manage methods processing using reflection API
EDITED TO SHOW IDEA
Following code taken from tutorial above just modified a little (see youListImpl.getRealArrayList() in invoke method)
public class DebugProxy implements java.lang.reflect.InvocationHandler {
private YouListImpl youListImpl;
public static Object newInstance(Object obj) {
return java.lang.reflect.Proxy.newProxyInstance(
obj.getClass().getClassLoader(),
obj.getClass().getInterfaces(),
new DebugProxy(obj));
}
private DebugProxy(Object obj) {
this.obj = obj;
}
public Object invoke(Object proxy, Method m, Object[] args)
throws Throwable
{
Object result;
try {
System.out.println("before method " + m.getName());
result = m.invoke(youListImpl.getRealArrayList(), args);
} catch (InvocationTargetException e) {
throw e.getTargetException();
} catch (Exception e) {
throw new RuntimeException("unexpected invocation exception: " +
e.getMessage());
} finally {
System.out.println("after method " + m.getName());
}
return result;
}
}

Categories