In a code base I am “starting from” there are a handful of interfaces with many default methods. They look something like this:

public interface HasXY {
   double getX();
   double getY();
   default double method1(double x, double y)  {...}
   default double method1(HasXY other)  {...}
   default double method2(double x, double y)  {...}
   default double method2(HasXY other)  {...}
   default double method3(double x, double y)  {...}
   default double method3(HasXY other)  {...}
   default double method4(double value)  {...}
   default double method5(double value)  {...}
}

At this time I have the option to refactor this code into an interface and a class. The outcome of this refactor will look somewhat like this:

public interface HasXY {
    XYPosition getXY();
}

public class XYPosition {
   double method1(double x, double y)  {...}
   double method1(XYPosition other)  {...}
   double method2(double x, double y)  {...}
   double method2(XYPosition other)  {...}
   double method3(XYPosition other)  {...}
   double method4(double value)  {...}
   double method5(double value)  {...}
}

I should note that the “source” code-base has several such interfaces and many classes implement a handful of these interfaces (leading to object that have many many methods). I am also at a unique moment in time where doing this refactor will be as easy as it ever will.

What are your thoughts on such a refactor? Is it a slam dunk “should do”? Do you think its a waste of time? Is it actually harmful because lose the succinct-ness of calling “myObject.methodFromOneOfSeveralDifferentInterfaces()”

2

The intention of the refactor is good. It takes verbosity out of implementors and bundle XYPosition-related methods to its own class, similar to what we do with parameter objets to avoid functions with a lot of paremeters. You are complying with the Interface Segregation Principle that states that clients should not know about methods they don’t need or use.

But an interface (an abstraction) should not depend on a concretion (a non-abstract class). Both abstraction and concretions should depend on abstractions. This is called the Dependency Inversion Principle. Things that change less often (interfaces) should not depend on things that change more often (implementations) but the other way around. So my suggestion is that you make XYPosition an interface, then move the implementation to a concrete XYPosition class (choose another name).

2