I have a problem with my interface-design. I especially ask for help with the overloaded compute-Method.

For a calculator I work with these Interfaces:

public interface ICalculator{
    public double compute(String expression) throws IllegalArgumentException;

public interface IParameterizedCalculator extends ICalculator {
    public double setParameter(String parameter, double value) throws IllegalArgumentException;

    public double getParameter(String parameter) throws IllegalArgumentException;

    // IllegalArgumentException when expression is null or malformed
    // IllegalStateException when a parameter in the expression was not set prior to this method
    double compute(String expression) throws IllegalArgumentException, IllegalStateException;

public interface IPersistentCalculator extends ICalculator {
    // IllegalStateException when no expression is stored
    double compute() throws IllegalStateException;

    void store(String expression) throws IllegalArgumentException;

IParameterizedCalculator adds an Exception to compute. As the previously stateless ICalculator suddenly became stateful I see no way than to add this exception.
IPersistantCalculator doesn't modify the original compute(String), but overloads it with compute(), which also has a state and therefore throws an IllegalStateException (but not necessarily an IllegalArgumentException, as the only way to store an expression is through the store(String)-Method and I don't care if someone hacks my code via reflection or debugger). However this IllegalStateException has a different reason (another "state" if you want).

I have three questions now:

  • How do I properly extend the throws-clause to indicate that my derived methods will throw more than their parent?
  • How do I communicate this in a class MyCalculator implements IPersistentCalculator, IParameterizedCalculator (which only exposes a single compute(String)-method)?
  • How do I communicate that the MyCalculator.compute()-Method may throw IllegalStateException when a parameterized expression has been stored?

I think if you continue this path you violate the "interface seggregation principle". Try to separate the interfaces. Going with your semantics I expect interfaces like ParameterAware or Storable. Then you won't get into such a semantical trouble.

As you have less semantical problems with your interfaces you will face other challenges that have to do with the implementing classes and your algorithms using and working with these seggregated interfaces. But you cannot escape it and the effort and it is justified.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.