2

Should an interface method implemented by a class always use all parameters? By interface I do not necessarily mean actual interfaces, these could be other (abstract) classes which are extended, too.

I sometimes find it hard to use all parameters in all implementations. However, that seems to me as bad design. It makes me think of the mantra perfection is achieved not when there is nothing more to add, but when there is nothing left to take away.

This especially applies in situations where (partially) optional behavior - such as flags that were previously set on the object instance - is refactored into an approach that makes use of polymorphism.

In pseudo code:

interface ValueProcesser {

    public Value doSomethingWithValue(value, parameter1, parameter2);
}

class Implementation1 implements ValueProcesser {

    // Does nothing - no optional behavior applies in here.
    public Value doSomethingWithValue(Value value, parameter1, parameter2) {
        return value;
    }
}

class Implementation2 implements ValueProcesser {

    // Behavior that only uses the first parameter
    public Value doSomethingWithValue(Value value, parameter1, parameter2) {
        doSomethingWithValueUsingParameter1(value, parameter1);

        return value;
    }
}

class Implementation3 implements ValueProcesser {

    public Value doSomethingWithValue(Value value, parameter1, parameter2) {
        doSomethingWithValueUsingParameter1AndParameter2(value, parameter1, parameter2);

        return value;
    }
}

Now for client code with a ValueProcesser instance, it is really easy to simply call:

    public void main() {
        ValueProcesser.doSomethingWithValue(value, parameter1, parameter2);
    }

and everything will work. The question is, should the unused parameters be refactored away somehow and how can I refactor to get rid of their redundancy?

For the record, it does not make sense to set those parameters as members of the Implementation classes.

user2180613
  • 1,752
  • 3
  • 14
  • 17
  • 1
    Not necessarily bad practice, but usually an indicator that something is not right. You are probably suffering from wrong abstraction. Your case seems to be similar to [another one](http://programmers.stackexchange.com/a/318500/193669), to which I have already given an answer on this board. – Andy Jul 24 '16 at 19:01

3 Answers3

3

In layman's terms:

As an implementor you are even allowed to write dummy implementations. You can just do nothing or return null (in the case of a function), or you can do something that is not what the method signature implies. But, will that achieve what you want?

It's perfectly valid for certain methods to accept null values in some parameters.

It's impossible to tell if you are incurring in a bad practice with examples like the ones you show. But chances are the interface violates the interface segregation principle and it's forcing you to implement methods that you don't need.

In the other hand, if parameter1 and parameter2 are just flags (you don't specify their type, so they could be booleans), then the design is flawed, because it implies that the method does more than one thing (Martin's Clean Code).

Bottom line:

You are being forced to implement a flawed design.

Kilian Foth
  • 107,706
  • 45
  • 295
  • 310
Tulains Córdova
  • 39,201
  • 12
  • 97
  • 154
  • Some people prefer a "wide" API with many methods. e.g. `doSomethingWithValue(Value value)` *and* `doSomethingWithValuePlusOPtions(Value value, Option option1)`, and even `doSomethingWithValuePlusTwoOptions(Vaue value, Option option1, Option option2)`. Others (including myself) prefer a more terse, compact API. – user949300 Jul 25 '16 at 22:18
1

Since many languages allow for optional parameters in a function signature, clearly this is not an "always bad" practice. As for guidelines for whether it is a good practice I'd suggest the following (Java based examples but should apply to other languages)

  1. Consistency: If there is a pattern of usage, such as a consistent optional "locale" argument for time and number formatting, that is good. If there are multiple options at the same place, like java.util.String having possible args for Charset and a String with the name of the Charset, that is suspect.

  2. Documentation: Where possible, use the language's builtin varargs syntax for clarity. In your example, the method should be public Value doSomethingWithValue(Value value, Value...options).

  3. Naturalness and Expressiveness: If all your coworkers "get it" quickly, you are on the right path. If everybody says "WTF why would I ever want an optional value fo PI?" you are likely going astray.

user949300
  • 8,679
  • 2
  • 26
  • 35
0

Your question is purely technical and has no practical examples. It is like asking "can I implement an interface method called Add to subtract the input values rather than add them up?"

Yes, you can, but the code will be useless. As will any interface implementation that does not implement the expected vehavior.

Take Substring. It takes a start and a length. Can you as an implementor ignore length? Yes, but any user will expect length to be effective when passed in. If you ignore any parameter your implementation will not be complete, each parameter on any interface method has a purpose.

Martin Maat
  • 18,218
  • 3
  • 30
  • 57
  • I provided no practical examples, because it is a general question: are unused parameters always bad practice? Some implementations of a strategy pattern may not need certain values to execute their functionality. For example, let's say I have an interface `Filterer` with a function `filter` that filters something (doesn't matter what) - I could imagine that some implementations need more parameters than others. Perhaps one implementation doesn't do any filtering at all: it merely returns that was to be filtered. This filter's implementation would simply return 100% of that was provided. – user2180613 Jul 24 '16 at 21:09
  • "I could imagine that some implementations need more parameters than others" That makes no sense. Any interface has a clearly defined behavior. It is not up to the implementer to decide whether an argument is important or not. If an implementer strays from the definition he is not implementing the interface, he would be implementing another interface. – Martin Maat Jul 24 '16 at 21:20
  • 1
    @MartinMaat: You are assuming an interface that defines the exact behaviour, with multiple implementations of the exact same behaviour. There are two mistakes: First, multiple implementations of the exact same behaviour are rare. More likely you have different behaviours that may be controlled by some parameter. And there are parameters that are mere hints. – gnasher729 Jul 25 '16 at 06:14
  • @gnasher An interface is a contract, not a suggestion. The issuer defines the contract and there will be no such thing as parameters for which the implementer redefines their meaning. So no, ignoring parameters is not a practical or meaningful scenario. – Martin Maat Jul 25 '16 at 07:46