0

Imagine the following class exists:

public class Foo extends Spam{
    public void bar(){};
    //...many more useful functions...
}

I now need this:

public class Fooish extends Foo{
    public static boolean whichDelegate; //true for 1, false for 2
    Foo delegate1;
    Foo delegate2;
}

Is there a way to automatically have java delegate the calls?

After looking over many other responses here on SO, I see three possible ways, none of which seem to work for my particular use case:

  1. Just override everything and do the switching logic yourself

    The problem with this is that Foo is a class that changes a lot. Doing this would mean that every time Foo is changed, Fooish must be changed also.

    Even worse, if it weren't changed and function eggs() were added to Foo, Fooish would call eggs itself rather than on its delegates. The chaos...

  2. One method class

    I would love to be able to do this, but Foo is a concrete class and lifting its functionality into an interface seems impossible. I can't touch Spam.

  3. Reflection

    Has significant performance impact and is hard for others to understand. Calls to the delegates probably won't be able to be found by eclipse, which will hurt maintainability. Seems like the best choice, but seems annoying for what should have a compile time solution.

I also found this but its in C#

Community
  • 1
  • 1
code11
  • 1,986
  • 5
  • 29
  • 37
  • 2
    Why not just have two different classes that delegate two different ways and then choose which one to use at a higher level in your code? Modern Java IDEs do automatic delegation code generation, so it shouldn't be too annoying to keep up with Foo changing.. – qwwqwwq Aug 29 '16 at 22:08

1 Answers1

2

If we are in control of the Foo consumer code, is the pattern below suitable?

public class FooDelegateSelector {
    public static boolean selectDelegate1; //true for 1, false for 2

    private Foo delegate1;
    private Foo delegate2;
    //delegates setup...

    public Foo getSelectedDelegate() {
        return selectDelegate1 ? delegate1 : delegate2;
    }
}

Foo consuming code:

final FooDelegateSelector fooSelector = new FooDelegateSelector(...);

final Foo selectedFoo = fooSelector.getSelectedDelegate();
selectedFoo.bar();

Note: I think this idea is close to the one suggested by qwwqwwq in his comments above.

Community
  • 1
  • 1
Andrew NS Yeow
  • 341
  • 2
  • 8
  • 1
    This makes sense. I believe that this is what I'm going to go with, even if it requires manually updating since its very clear whats happening. I'll leave the question open for a bit more if anyone has additional things to add. – code11 Aug 30 '16 at 13:04