Medya Gh
Medya Gh

Reputation: 5023

What design pattern to use for a method implementation which is repeated in all classes implementing same interface?

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

Answers (5)

Despertar
Despertar

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

cat916
cat916

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

Stephen C
Stephen C

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

Radiodef
Radiodef

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

Saeed
Saeed

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

Related Questions