2016-08-29 2 views
0

Представьте себе следующий класс существует:Условные Делегаты в Java

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

я теперь это нужно:

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

Есть ли способ автоматически Java делегировать вызовы?

После просмотра многих других ответов здесь на SO, я вижу три возможных пути, ни один из которых, кажется, работают для моего конкретного случая использования:

  1. Just override everything and do the switching logic yourself

    Проблема с этим состоит в том, что Foo - это класс, который сильно меняется. Выполнение этого будет означать, что каждый раз, когда Foo изменяется, Fooish также должен быть изменен.

    Хуже того, если бы он не был изменен, и функциональные яйца() были добавлены в Foo, Fooish называл бы сами яйца, а не его делегаты. Хаос ...

  2. One method class

    Я хотел бы быть в состоянии сделать это, но Foo является классом бетона и подъем его функциональности в интерфейс кажется невозможным. Я не могу коснуться Спама.

  3. Reflection

    Оказывает значительное влияние на производительность и трудно для других, чтобы понять. Вызовы делегатов, вероятно, не смогут быть обнаружены затмением, что повредит ремонтопригодности. Похоже, что это лучший выбор, но кажется раздражающим для того, что должно иметь решение времени компиляции.

Я также нашел this, но его в C#

+2

Почему не просто два разных класса, которые делегируют два разных способа, а затем выбирают, какой из них использовать на более высоком уровне в вашем коде? Современные Java-IDE делают автоматическое создание кода делегирования, поэтому не должно быть слишком раздражающим, чтобы идти в ногу с изменением Foo. – qwwqwwq

ответ

2

Если мы в контроле Foo потребительского кода, является рисунок ниже подходит?

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 потребляя код:

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

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

Примечание: Я думаю, что эта идея близка к одной предложенной qwwqwwq в его comments выше.

+1

Это имеет смысл. Я считаю, что это то, с чем я собираюсь идти, даже если это требует ручного обновления, так как это очень ясно, что происходит. Я оставлю вопрос открытым еще немного, если у кого есть дополнительные вещи, которые нужно добавить. – code11

+0

@ code11 Спасибо за согласие. : D –

Смежные вопросы