tags:

views:

94

answers:

4

Hi all,

I have an OOP-related question. I have an interface, say:

class MyInterface {
    public int getValue();
}

In my project, this interface is implemented by 7 implementations:

class MyImplementation1 implements MyInterface { ... }
...
class MyImplementation7 implements MyInterface { ... }

These implementations are used by several different modules. For some modules, the behaviour of the MyInterface must be adjusted slightly. Let's that it must return the value of the implementator + 1 (for the sake of example). I solved this by creating a little decorator:

class MyDifferentInterface implements MyInterface {
   private MyInterface i;

   public MyDifferentInterface(MyInterface i) {
       this.i = i;
   }

   public int getValue() {
       return i.getValue() + 1;
   }
}

This does the job.

Here is my problem: one of the modules doesn't accept an MyInterface parameter, but MyImplementation4 directly. The reason for this is that this module needs specific behaviour of MyImplementation4, which are not covered by the interface MyInterface on itself. But, and here comes the difficulty, this module must also work on the modified version of MyImplementation4. That is, getValue() must return +1;

What is the best way to solve this? I fail to come up with a solution which does not include lots of code duplicates.

Please note that although the example above is pretty small and simple, the interface and the decorator is quite large and complicated.

Thanks a lot all.

A: 

Declare getValue with the virtual keyword in MyImplementation4.

Inherit a new class from MyImplementation4 and use the override keyword to declare the getValue function and implement it as return base.getValue()+1.

Rice Flour Cookies
Thanks for your answer. The decorator MyDifferentInterface is very complicated and contains a lot of code. This solution means that I have to copy all this code.
Karel J
OP is using Java syntax; Java has no `virtual` keyword (methods are virtual by default!)
BlueRaja - Danny Pflughoeft
Why can't you declare a new class that inherits `MyImplementation4` and override only the method that you have to change the return value for? It sounds straight-forward to me.
Rice Flour Cookies
+2  A: 

If it is in Java, you can do

class ModifiedMyImplementation4 extends MyImplementation4
{
    @Override
    public int getValue()
    {
        return super.getValue() + 1;
    }
}

No code duplication!

quant_dev
+1 though of course, *best* option would be to fix the design of the other module, but this may not be possible.
BlueRaja - Danny Pflughoeft
+1, or if you don't want to inherit, pass an instance of `MyImplementation4` into the constructor and delegate the unchanged operations to that instance.
Jeff Sternal
Or just add a switch to MyImplementation4 which makes it increased the return value of getValue() by 1, if set to true.
quant_dev
A: 

You could try something like:

public class MyDifferentImplementation4 extends MyImplementation4 {
    private MyDifferentInterface mdi;
    public MyDifferentImplementation4(MyDifferentInterface mdi) {
        this.mdi = mdi;
    }
    public getValue() {
        return mdi.getValue();
    }
}

The MyDifferentInterface instance passed to the constructor should wrap an instance of MyImplementation4 (you could enforce that by using a subclass of MyDifferentInterface whose constructor took an instance of MyImplementation4 rather than the interface).

Jonathan
A: 

This solution means that I have to copy all this code

Can't you put the code that would be duplicated into an abstract class MyAbstractImplementation ? Then the two child classes can inherit from the abstract class. All it needs to have is a single abstract method which doesn't even have to do anything, it just has to be implemented by the children.

void foo(void);

The child that needs a different behavior overrides the method. The consumer would need to accept the MyAbstractImplementation type instead of the interface. Voila, no code duplication.

Kelly French