Reputation: 5023
I was trying to make an objected oriented examples out of "union find".
so I have an interface called UF,
public interface UF {
boolean connected(int p,int q);
void printArray();
void union(int p,int q);
}
and the following classes implement it quickFindUF,quickUnionUF,quickWeightedUnionUF but all of them share a function which is identical in implementation, (the function printArray())
what is the best pattern to use to avoid printArray() code to be repeated ? do I create a class call ArrayPrinter and pass the array to it in the printArray() in all of those classes which implement UF ?
Is there any pattern that I can do this without doing abstract inheritance and just use interfaces. because inheritance limits my design, if I inherit a class I wont be able to inherit anything else, I don't make that limitation just for a printArray() method ...
Upvotes: 0
Views: 2234
Reputation: 22362
Interface-segregation principle suggests splitting different functionality into separate interfaces. In this case your printArray()
method is a responsibility that can be separated from the UF interface.
You implement an ArrayPrinter
interface and you pass arrays to it. This also keeps in line with the single responsibility principle as well as facilities decoupled architecture. You're UF interface doesn't know anything about the printing, that is a separated responsibility so it is handled by a different object.
Upvotes: 0
Reputation: 1361
In Java 8, you could do it with Default method
Interface Methods
Default methods and abstract methods in interfaces are inherited like instance methods. However, when the supertypes of a class or interface provide multiple default methods with the same signature, the Java compiler follows inheritance rules to resolve the name conflict. These rules are driven by the following two principles:
Instance methods are preferred over interface default methods.
Methods that are already overridden by other candidates are ignored. This circumstance can arise when supertypes share a common ancestor.
So your code would be
public interface UF {
default public void printArray() {// Provide default implementation }
}
Upvotes: 1
Reputation: 718768
Is there any pattern that I can do this without doing abstract inheritance and just use interfaces.
In Java 8, you can declare default methods in interfaces. The limitation is that a default method cannot depend on instance variables declared by implementation classes. They have to rely entirely on the classes public API to access or update the object state.
For the cases where default methods are applicable, they avoid the need to extend a common base class, while also avoiding the cumbersomeness of delegation.
Upvotes: 1
Reputation: 37845
You are thinking of delegation. I would personally not call it a design pattern because it's just a compositional technique but anyway there is a Wikipedia article calling it one.
In this example, UnionFind extends ArrayPrinter
so that the ArrayPrinter
interface is propagated throughout the composite. The delegate implements a piece of the hierarchy:
interface ArrayPrinter {
void printArray();
}
interface UnionFind extends ArrayPrinter {
boolean isConnected(int p, int q);
void makeUnion(int p, int q);
}
class DefaultPrinter implements ArrayPrinter {
@Override
public void printArray() {
/**
* do actual print
*/
}
}
class QuickFind implements UnionFind {
private final ArrayPrinter printDelegate = new DefaultPrinter();
@Override
public void printArray() {
printDelegate.printArray();
}
/**
* the rest
*/
}
Upvotes: 1
Reputation: 7370
You can have an abstract class AbstractUF like this:
public abstract class AbstractUF implements UF{
public abstract boolean connected(int p,int q);
public void printArray() {
//implementation
}
public abstract void union(int p,int q);
}
and inherit your classes from AbstractUF, so just (override and) implement other 2 functions
Upvotes: 2