I have a base class that captures some functionality common to two classes. In other words, I can create one base class and make these two classes subclasses of that base class. However, for each of these sub classes, the number of instances can be created is 1 (i.e. each sub class has to be a singleton).
I googled and found that there's a reasonable debate going on over this. Although there are several solutions available, I am not sure whether they would fit in my case.
can anyone tell me how I should design this?
You can make each class separately a singleton, and make the base class abstract. Not sure what's the debate -- just that singletons, in general, aren't a great idea?
Use the Abstract factory pattern. Have a separate class with methods to retrieve the singletons, and let it hold the references to the singletons in instance variables or in a map.
You may not want the increased complexity, but frameworks like Spring were created to solve these kind of issues (among others).
It seems that Pico Container is alive and well, and it may be the simplest while still solid solution. Look at the inversion of control topics, and let the framework inject the singletons where you need them.
In short, don't try to make the singletons manage access to themselves. Delegate that on something else.
There's nothing inherently wrong in having singleton classes with complex inheritance. In fact, class hierarchies with private constructors (no instances) are very useful in many situations. You just have to decide how you want to manage the two important aspects of singletons: creation, and access.
I don't know if you need an example but I gave it a try. Without knowing any of your details this example is very vague. I am also here to learn so let us know what you end up implementing.
The Base class:
public abstract class BaseClass {
public void someMethod() {
System.out.println("base class hello: " + this);
}
public abstract void someOtherMethod(String value);
}
One of the subclasses:
public class SubClassOne extends BaseClass {
private static SubClassOne instance;
private SubClassOne() {}
public static SubClassOne getInstance() {
if (instance == null) {
instance = new SubClassOne();
}
return instance;
}
public void someOtherMethod(String value) {
someMethod();
System.out.println("sub class hello: " + value + " " + this);
}
public static void main(String[] args) {
SubClassOne one = SubClassOne.getInstance();
SubClassOne two = SubClassOne.getInstance();
SubClassOne three = SubClassOne.getInstance();
SubClassOne four = SubClassOne.getInstance();
one.someOtherMethod("one");
two.someOtherMethod("two");
three.someOtherMethod("three");
four.someOtherMethod("four");
}
}
I had a similar requirement: I had multiple cache maps with repeating methods and members, so I've created an abstract class like:
public abstract class AbstractCache<T> {
protected final Map<String, T> cache;
protected AbstractCache() {
this.cache = getDefaultExpiringMap(TimeUnit.HOURS.toMillis(4));
}
public Map<String, T> getCache() {
return cache;
}
public T getAll(String id) {
return cache.get(id);
}
}
Then I've extended this class and created a singleton instance:
public final class FooCache extends AbstractCache<Set<Integer>> {
public static final FooCache INSTANCE = new FooCache();
private FooCache() {
super();
}
public void add(String fooId, Integer value) {
cache.computeIfAbsent(fooId, k -> new HashSet<>()).add(value);
}
}
And the usage:
public static void main(String[] args) {
FooCache.INSTANCE.add("a", 1);
System.out.println(FooCache.INSTANCE.getAll("a"));
}
I'm not an expert in Java, so I don't know if this is technically legal Java code (perhaps another poster can comment):
Make the base classes inherit from a generic class Singleton.
Example:
class Singleton<T> {
protected Singleton(); //constructor
private static T _instance;
}
class DerivedOne extends Singleton<DerivedOne>{
protected DerivedOne(){} //constructor
}
class DerivedTwo extends Singleton<DerivedTwo>{
protected DerivedTwo(){} //constructor
}
Inheritance is not the only way to re-use common functionality. Containment may be preferable in the general case.
Consider the following solution in which class A and B are the singletons, and the common functionality is in class AB, but instead of extending AB, both A and B use an instance of AB which is a singleton itself.
class AB { //common functionality of A and B
//singleton pattern here
//common data and functionality here
}
class A {
private AB ab = AB.getInstance();
//singleton pattern here
//unique functionality and data of A
//to use any of the functionality in AB delegate to member ab
}
class B is similar to A.
in this solution there is a single instance of every data and functionality of both A and B (and AB)
Note that if clients of A and B need to access the common public methods in AB, then
AB, A and B should implement an interface of those public methods, and A and B implementation should delegate the call to ab.
The solution proposed by Ernest below, may be a shortcut in some situations, but in general is a wrong solution.
To explain why Ernest's solution may be wrong, let's describe that solution in a different way.
Suppose i have a singleton class A and i discover that i need to write another singleton class B, but i need some of the functionality of A in B. So i factor out the common data and functionality of A into an abstract class AB and make both A and B extend AB.
The reason why it's wrong, in general, is because this solution takes a subset of the data and functionality which is supposed to exist only once, and places it in a sub-class (AB), effectively and potentially duplicating it in every sub-class that will be created. Now, after getting an instance of A and an instance of B, you have two instances of the subset data and functionality in AB.
If for example, the common functionality placed in the base class writes some initial data to the file named "myData", then both of your singletons will execute this code even though it was only meant to be executed once, and when the later executes it it will wipe out the file created by the former.
Therefore, in general, the solution described here does not use inheritance, and ensures that a singleton encapsulates the common functionality as well as the singleton classes that use it.
Related
I'm trying to implement something to this effect:
Base class A has a method getFileName()
Two derived classes B and C have overridden implementations of that method, returning file names specific to B and C.
Class A needs to use the services of a singleton class S
The reason I want it to be a singleton is because (a) I want a guarantee that it will only be constructed once and (b) I want eager initialization of that class, which happens at app startup, and not at first use.
Class S needs to do its work work based on the file name (E.g., read in the contents of that file) - which depends on which of A's subclasses is used.
This seems to present an unavoidable conundrum, because:
most implementations of Singleton are static based (pure static class; or ENUM with a static parameter passing)
static classes/methods/blocks cannot call non-static methods...
... and making getFileName() static will make sure that it cannot use inheritance overrides!
How can I implement this design? (I'm open to changing the design if a better pattern is available)
... needs to use the services of a singleton ... which depends on which of A's subclasses is used:
That means the Singleton is not really your problem, it is the acquisition of the correct class based on the type asking!
Your design is too tightly coupled the way you are trying to do it. You need to completely decouple the Service from the Consumers of the service, Singleton is not important in this exercise.
What you need is some form of dependency injection.
This is exactly the type of problem that Guice was created to solve by being able to provide what classes get injected based on another classes type in a binding. That said ...
Most people do not realize that Java has always supported DI via the Constructor. Guice makes this less hard coded, but it is still a dependency that is injected to an instance.
Guice would make this trivial by injecting the correct service based on the class type. But it can be done without any DI framework/library. If using Guice is considered to heavy handed for your case then it can still be done easily.
Below is one way to do it without a framework/library:
public class Solution
{
static class Singleton
{
public static final Singleton INSTANCE;
static { INSTANCE = new Singleton(); }
private Singleton() { /* this is important */ }
public void doWhatever(#Nonnull final B b) { /* whatever */ }
public void doWhatever(#Nonnull final C c) { /* whatever */ }
}
static abstract class A
{
private final Singleton s;
public A(final Singleton s) { this.s = s; }
public abstract String getFilename();
}
static class B extends A
{
public B(final Singleton s) { super(s); }
#Override
public String getFilename() { /* code goes here */ }
}
static class C extends A
{
public C(final Singleton s) { super(s); }
#Override
public String getFilename() { /* code goes here */ }
}
}
The singleton anti-patterns you mention are just that:
The Singleton pattern should by hidden behind a Factory pattern. Your consumers of what needs to have 1 and only 1 should not care if there is 1 and only 1. They should only care that that object conforms to some contract of some interface.
My implementation is a naive Factory to create in static block. Most are create on first use which is not any better.
Using Enum to create Singleton objects is a misuse of the semantics of Enum and an anti-pattern and impossible to properly unit test.
Same with the all static utility class approach, impossible to unit test or replace with a different implementation. A combination of the two is a complete abomination that is impossible to unit test and a complete nightmare to maintain!
How you determine which subclass of A the Singleton works on is easy:
That is what overloading is for as shown in the code above.
Anything else is not doing it right. instanceof fail, reflection bigger fail.
Selecting logic based on Type can be done with overloading methods, or generics or with the appropriate design pattern.
Strategy Pattern would account for that easily and make N number of subclasses manageable and extensible at runtime.
I think you need to decide if S uses A or if A uses S.
If S uses A, then A could be a base class or interface, and S would have a method that accepts instances of A, which are overridden with the correct implementation of getfileName().
If A uses S, then A should be abstract with respect to getFileName() forcing an implementation to be constructed, and it should internally call it's yet-to-be-defined getFileName() passing that as an argument to S.
Singletons are the glue between Object-Oriented solutions and non-Object-Oriented solutions, so you avoid the conundrum by
Having your objects passed to the non-object oriented singleton "utility routine"
Having the resolved parameters passed to the non-object oriented singleton "utility routine"
Example code for the first technique
// this could be abstract class too, as long as getName() is abstract
public interface Nameable
public String getName();
}
public enum Utility {
INSTANCE;
public static deleteByName(Nameable nameable) {
createBackup(nameable.getName());
updateIntentLog(nameable.getName());
removeFile(nameable.getName());
updateAuditLog(nameable.getName());
}
}
or
public abstract class Nameable {
public abstract String getName();
public void delete() {
Utility.INSTANCE.deleteFile(getName());
}
}
public enum Utility {
INSTANCE;
public void deleteFile(String name) {
...
}
}
You can make singleton classes that you initialize manually, i.e. have a static instance variable but also a static initialize() method. The initialize throws if you try to initialize twice. This allows you to choose at run-time which subclass to use and also it makes the initialization order clear.
It's hard to explain, but it's simple to show a snippet of Ruby code:
Have two modules that implement methods:
module Foo
def one
print "ONE!"
end
end
module Bar
def two
print "TWO!"
end
end
Have a class that includes them:
class Test
include Foo
include Bar
end
Now your class Test can call those two methods.
As far as I'm aware, there isn't something like this in Java. Close concepts would be:
Multiple inheritance
Which is not supported by Java.
Interfaces
They're method contracts - there is no implementation. Your class Test would need to implement the methods itself, and that's what I want to avoid. Simply for the sake of not writing the same code twice (I have several other classes, some of them may want to implement those methods too).
Abstract classes
I'd still need to inherit from two classes at the same time.
So what is the recommended solution here?
In Java 8 you could achieve this using default methods but that was never the intent of defaults so this may be bad advice:
interface Foo {
default void one () {
System.out.println("ONE!");
}
}
interface Bar {
default void two () {
System.out.println("TWO!");
}
}
class FooBar implements Foo, Bar {
}
public void test() {
FooBar fooBar = new FooBar();
fooBar.one();
fooBar.two();
}
However, I would like to reiterate what #Thomas said in his comment The need for multiple inheritance is often a sign of a flaw in the design.
The easiest solution is to create hierarchical inheritance as so :
public class foo
{
public void one()
{
System.out.println("ONE!");
}
}
public class bar extends foo
{
public void two()
{
System.out.println("TWO!");
}
}
class Test extends bar
{
//this class now has access to both methods from the two classes
}
Favour composition over inheritance. So your class would have references to both implementing classes.
MyClass {
ClassA
ClassB
}
Th alternative of subclassing twice, seems rather hacky to me and would lead to an unnecessarily complex inheritance tree.
Or with java 8's new static methods (as opposed to default which can be overridden). See comparator for examples.
interface X
{
static void foo()
{
System.out.println("foo");
}
}
interface Y
{
static void bar()
{
System.out.println("bar");
}
}
MyClass implements X, Y {
public static void main(String args[])
X.foo();
}
The interface name must be used as prefix, as static method is part of interface.
There are few solutions that might solve your case. You can use the Visitor Pattern or Strategy Pattern.
In both cases you will benefit from Interfaces and Composition.
Your class Test would need to implement the methods itself, and that's what I want to avoid.
Well, yes, but that "implementation" could just be a simple delegation (and your IDE can create the code for this wrapper automatically).
public String one(){
return foo.one();
}
The actual code can be in class Foo, and be shared (as in "used") among many classes.
I have a series of classes, A,B,C... (several dozen in total) that share common code. There can be many instance of each class A,B,C... . I'm planning to create a superclass, Abstract, that will contain that code instead.
Problem is, the common stuff works on an object that is unique on a per-class (not per-instance) basis. This is currently solved by A,B,C... each having a static field with the corresponding value. Obviously, when I refactor the functionality into Abstract, this needs to be changed into something else.
In practice, it currently looks like this (note that the actual type is not String, this is just for demonstrative purposes) :
public class A implements CommonInterface {
private static final String specificVar = "A";
#Override
public void common() {
specificVar.contains('');
}
}
public class B implements CommonInterface {
private static final String specificVar = "B";
#Override
public void common() {
specificVar.contains('');
}
}
The best idea I've come up with until now is to have a Map<Class<? extends Abstract>,K> (where K is the relevant type) static field in Abstract, and A,B,C... each containing a static initalization block that places the relevant value into the map. However, I'm not convinced this is the best that can be done.
Note that I'm not using any DI framework.
So, what would be the most concise, in terms of code contained in the subclasses, way to refactor the static fields in A,B,C... handled by the common code, without sacrificing field access efficiency?
Perhaps an enum is what you want.
enum MyInstances implements MyInterface {
A {
fields and methods for A
}, B {
fields and methods for B
};
common fields for all MyInstances
common methods for all MyInstances
}
// To lookup an instance
MyInstances mi = MyInstances.valueOf("A");
As you haven't shown any source code, we can't really tell if the use of static fields is a good or a bad design choice.
Considering the use of static fields by the subclasses is indeed a good design choice, the first way of having common code in a superclass to access them is by calling abstract methods that would be implemented in the subclasses.
Example:
public abstract class SuperClass {
public void processCommonLogic() {
// Common logic
// Execute specific logic in subclasses
processSpecificLogic();
}
public abstract void processCommonLogic();
}
public class ASubClass extends SuperClass {
public static int SPECIFIC_SUBCLASS_CONSTANT = 0;
public void processSpecificLogic() {
// Specific subclass logic
doSomethingWith(ASubClass.SPECIFIC_SUBCLASS_CONSTANT);
}
}
You could use the Template Method Pattern.
Have an abstract method getValue() defined in your abstract class and used within your abstract class wherever you require the value. Then each of your subclasses simply need to implement the getValue method and return the correct value for that subclass.
Static method M returns an object implementing interface A:
interface A { ... }
static A M() { ... }
Within M I would like to construct an object of type B and return that, given that B implements A:
class B implements A { ... }
I do not want client code to know anything about how B is implemented, I would prefer for B not to be a static class, B must be immutable and there could be different B handed to different clients. I want to prevent instantiation of B outside method M at all costs (short of reflection, as one user commented).
How can I achieve the above? Where and how should I implement B? Could you please provide a short code example?
My main problem is: how can I have "different Bs?"
A static inner class is probably your best bet. You won't be able to "prevent instantiation of B at all costs" since with reflection, client code can bypass all access modifiers.
You can use anonymous inner class that won't be called B (is anonymous) but will implement A for example
interface A {
void someMethod();
}
public class Test {
static A M() {
return new A() {// it will create and return object of anonymous
// class that implements A
#Override
public void someMethod() {
}
};
}
}
Without using reflection object of anonymous class can be created only by method M. Also it can't be extended so it is good first step to immutability.
You could also use a Proxy implementation to hide the implementation class further
public interface A {
public Object getValue();
}
public class Factory {
public static A newInstance() {
return new ProxyA(AImpl);
}
}
public class ProxyA implements A {
private A proxy;
public ProxyA(A proxy) {
this.proxy = proxy;
}
public Object getValue() {
return proxy.getValue();
}
}
All this is really doing is hiding the implementation of A under another layout and makes it difficult to create a instance of ProxyA
But as #Asaph points out, with reflection, it becomes next to near impossible to truly guard against people accessing various parts of the classes and objects...
You could also separate your interface and implementations via different Classloaders, so that you only ever expose the interface's to the developers and implementations are delivered by dynamic class loading them at runtime. While not solving the underlying problem, it further complicates the matters for those trying to circumvent your factory.
IMHO
I understand what an abstract class is in OOP paradigm. Yeah an abstract class is an incomplete type, cannot be instantiated.
Subclasses of the abstract class can extend the superclass and so on, and call a method through using a base type variable. But that is what I don't get.
I was reading the book, and the author said using a Superclass variable to reference a subclass and calling a common method calls the correct method. And yeah that's true. For example this little code I wrote:
public class ObjectOne extends SuperObject {
public String objectString()
{
return "objectString() of class ObjectOne\n" ;
}
}
public class ObjectTwo extends SuperObject {
public String objectString()
{
return "objectString() of class ObjectTwo\n" ;
}
}
public class ObjectThree extends SuperObject {
public String objectString()
{
return "objectString() of class ObjectThree\n" ;
}
}
public class SuperObject {
public String objectString()
{
return "SuperObject" ;
}
}
import static java.lang.System.out ;
public class ControlClass {
public static void main(String[] args)
{
SuperObject [] arr = {new ObjectOne(), new ObjectTwo(), new ObjectThree()} ;
for(SuperObject elem:arr)
{
out.println(elem.objectString()) ;
}
}
}
Em, so when main executes the correct methods are called for the objects using just the reference type. My question is so what is the point of an abstract class? Polymorphism works regardless of whether the method or class is abstract.
Unlike C++, polymorphism works only when you specify it. For Java, it works apparently all the time.
So I guess the abstract keyword or abstract concept is just to complete the inheritance hierarchy, make incomplete types impossible to instantiate, or is to promote good OOP practice? Can someone clarify thanks.
I'm not sure you understand what an abstract class is, as none of the classes in your example are abstract, and nothing in there is an interface either. What you are doing is extending an instantiable class. Without the abstract keyword there is nothing to stop me doing:
SuperObject obj = new SuperObject();
I think a better example would be to illustrate how abstract classes are used. What they are commonly used to do is to provide a common method implementation. If a number of classes implement some interface, but all of them implement the same method in the same way using the same code, then what is commonly done is to create an abstract class that contains the common implementation, and get all of the concrete implementations to extend that class. This facilitates code reuse, and decreases the likelihood that one developer will change the common method implementation for one class, but forget the others. For example..
public class ObjectOne extends Thing {
public String objectString()
{
return "objectString() of class ObjectOne\n" ;
}
}
public class ObjectTwo extends Thing {
public String objectString()
{
return "objectString() of class ObjectTwo\n" ;
}
}
public class ObjectThree extends Thing {
public String objectString()
{
return "objectString() of class ObjectThree\n" ;
}
}
public abstract class Thing implements SuperObject {
public String alwaysTheSame() {
return "The same thing";
}
}
public interface SuperObject {
public String objectString();
public String alwaysTheSame();
}
import static java.lang.System.out ;
public class ControlClass {
public static void main(String[] args)
{
SuperObject [] arr = {new ObjectOne(), new ObjectTwo(), new ObjectThree()} ;
for(SuperObject elem : arr)
{
out.println(elem.alwaysTheSame());
out.println(elem.objectString()) ;
}
}
}
What we have done here is introduce an abstract class Thing, which provides a method implementation that is common to all 3 implementations of SuperObject (which is now an interface). This means we don't have to write the same code again in three different places in order to to fully implement the SuperObject interface in each one of our concrete classes.
In addition to this, you can also extend non final classes. You may wish to do this in order to override the default behaviour of one or methods on the concrete class, or to decorate the the class with additional methods. Of course, when you are designing a class hierarchy from scratch you don't stick concrete classes in it that then get extended by other classes, as it's generally considered a bad code smell. However, few of us work with totally new written-from-scratch codebases, and must adapt an exiting codebase to new requirements. Extending a concrete class is one tool in the toolbox to do this.
EDIT: Misunderstood what the OP was asking, but the last paragraph above is relevant.
Let's say you want to deploy an application on an Ipad, Android, Iphone and Desktop application.
You work on an important part that will do 95% of the job in an abstract class. Then you create 4 other small classes that will implement the abstract method differently for each device.
That way, you won't repeat 95% of the work, and each device will instanciate his own class, that extends the abstract common class.
Abstract classes are an excellent way to create planned inheritance hierarchies. They're also a good choice for nonleaf classes in class hierarchies.
Here's a good detailed explanation: (extracted from here)
Choosing interfaces and abstract classes is not an either/or proposition. If you need to change your design, make it an interface. However, you may have abstract classes that provide some default behavior. Abstract classes are excellent candidates inside of application frameworks.
Abstract classes let you define some behaviors; they force your subclasses to provide others. For example, if you have an application framework, an abstract class may provide default services such as event and message handling. Those services allow your application to plug in to your application framework. However, there is some application-specific functionality that only your application can perform. Such functionality might include startup and shutdown tasks, which are often application-dependent. So instead of trying to define that behavior itself, the abstract base class can declare abstract shutdown and startup methods. The base class knows that it needs those methods, but an abstract class lets your class admit that it doesn't know how to perform those actions; it only knows that it must initiate the actions. When it is time to start up, the abstract class can call the startup method. When the base class calls this method, Java calls the method defined by the child class.
You also don't have to implement certain methods in abstract classes. You can decide what have to be declared in Subclasses and what you want declare in the Superclass.
Look at OutputStream for example:
public abstract void write(int i) throws IOException;
public void write(byte abyte0[]) throws IOException {
write(abyte0, 0, abyte0.length);
}
public void write(byte abyte0[], int i, int j) throws IOException {
if(abyte0 == null)
throw new NullPointerException();
if(i < 0 || i > abyte0.length || j < 0 || i + j > abyte0.length || i + j < 0)
throw new IndexOutOfBoundsException();
if(j == 0)
return;
for(int k = 0; k < j; k++)
write(abyte0[i + k]);
}
You have an abstract write method (because you don't knwo where the OutputStream is going to) but all other extra write methods are not abstract and forwarded to this methods. So you only have to declare one method in the Subclass and have some methods "extra" without having to implement it in every Subclass.
You may want a class not to have any instances.
For example assume you have a Person class and two classes derived from it Student and Teacher. In this case you may not want to have any objects created from Person class as it may not have any meaning for your program.
The "point" is to enforce a class hierarchy, potentially with some functionality provided by base class(es), and force some behavior to be implemented by sub-classes.
You would use an abstract class in cases where you do want to specify certain behaviour but don't want anybody to instatiate it directly but having to subclass it.
An abstract class can be full bodied or the skeleton for the subclass. You define your template in the abstract class and its left for the subclass to extend and implement the methods defined in the superclass.
So I guess the abstract keyword or abstract concept is just to complete the inheritance hierarchy, make incomplete types impossible to instantiate, or is to promote good OOP practice?
My answer is yes to everything that you said.
Along with what others have said, you may be using a library written by someone else, where you don't have access to the source code, but want to change it's behavior.