В чем разница между реализациями класса «Listener»? - PullRequest
0 голосов
/ 14 января 2011

Я попал в другой «философский» вопрос относительно Java.Речь идет о следующем сценарии:

У вас есть класс T, который определяет интерфейс L, который должен использоваться в качестве прослушивателя, уведомителя для второго класса.

Теперь выиметь второй класс (в следующем коде это классы A и B).Этот класс создаст новый объект класса T и использует L, который последний будет использовать для связи с первым.

Итак, я представляю 4 разные версии того, как он может передавать объект Listener.T:

  • Классы A определяют реализацию L, класс LL и используют его новый объект для создания T класса.

    1. A1 предварительно выделяет объект
    2. A2 создает на месте новый объект
  • Классы B useвстроенный способ создания объекта с использованием анонимных классов L (спасибо Тиму Бендеру за исправление)

    1. B1 предварительно выделяет объект
    2. B2 создаетновый объект на месте

Мой вопрос: является ли какая-либо из этих версий более эффективной в той или иной мере?Кто-то из них по какой-то причине небезопасен?Пожалуйста, обсудите, предложите другие версии и объясните!

Класс T

class T extends TT{
    public interface L{
        public void do(int i);
    }

    private L Lo;

    T(L i){
        Lo = i;
    }

    public void start(){
        // do stuff
        L.do(0);
    }
}

Класс A

class A1{
    private class LL implements L{
        @Override
        public void do(int i){
            // do stuff
        }
    }

    private LL l = new LL();

    public void function(){
        T t = new T(l)
    }
}

class A2{
    private class LL implements L{
        @Override
        public void do(int i){
            // do stuff
        }
    }

    public void function(){
        T t = new T(new LL())
    }
}

Класс B

class B1{
    private L l = new L(){
        @Override
        public void do(int i){
            // do stuff
        }
      };

    public void function(){
        T t = new T(l);
    }   
}

class B2{
    public void function(){
        T t = new T(new L(){
            @Override
            public void do(int i){
                // do stuff
            }
        });
    }   
}

Ответы [ 2 ]

2 голосов
/ 14 января 2011

На самом деле нет существенной разницы в эффективности программного обеспечения Это действительно сводится к эффективности программиста и большему контексту. Если вы точно знаете, что он будет использоваться только один раз, тогда B2, как правило, предпочтительнее, поскольку он более лаконичен. A1 является более многословным, но также более пригодным для повторного использования. Кроме того, выбирая правильные имена переменных, многословность лучше подходит для самодокументируемого кода, если он вообще сложен.

Моя личная тенденция - это третий вариант, когда внешний класс реализует интерфейс, и this передается в конструктор.

2 голосов
/ 14 января 2011

Разница между A и B (с использованием анонимных классов) не является разницей времени выполнения. Когда вы компилируете этот код, вы обнаружите, что анонимный класс создается с использованием идентификатора, например B1 $ 1. Вы даже можете просмотреть этот файл класса в каталоге bin, в который вы скомпилировали.

Единственная разница между 1 и 2 состоит в том, что, создавая переменную-член, вы увеличиваете размер, необходимый для создания экземпляра содержащего класса. Вы должны создавать переменную-член только в том случае, если это необходимо (для повторного использования).

Самое главное, однако, первоочередными задачами при разработке всегда должны быть ясность и правильность. Если впоследствии возникает проблема с производительностью, гораздо лучше обратиться к работающему приложению с инструментом анализа, который определит проблемные области. Или, возможно, используйте инструмент статического анализа, чтобы определить небольшой, но легкий выигрыш (низко висящий фрукт).

...