Может ли IntelliJ автоматически создать класс декоратора? - PullRequest
20 голосов
/ 01 декабря 2010

Иногда я создаю класс декоратора следующим образом:

class MyInterfaceDecorator implements MyInterface {
   private final MyInterface delegate;
   ... constructor taking a MyInterface instance ...

   @Override
   public Object someInterfaceMethod(Some argument) {
       return delegate.someInterfaceMethod(argument);
   }

   ... etc, more methods here...
}

Может ли IntelliJ автоматически создать этот класс для меня?

Ответы [ 2 ]

39 голосов
/ 01 декабря 2010

Обновление //

Я заметил, что у IntelliJ есть опция «Генерировать» для генерации методов делегата. Создать новый класс:

public class MyDecoratorClass {
    private MyInterfaceWithManyMethods myInterface;
}

Затем отметьте myInterface, перейдите в Меню> Код> Методы делегирования, выберите все методы, которые вы хотите обернуть, и все.

// Конец обновления

Вы можете попробовать рефакторинг «Рефакторинг» -> «Заменить наследование делегированием». Это должно быть в состоянии сделать это, как это. Я называю это «Код с помощью Alt + Enter»

Перейдите к интерфейсу, для которого вы хотите сгенерировать декоратор.

public interface MyInterfaceWithManyMethods {
    void method1();
    void method2();
    void method3();
}

Нажмите Alt + Enter, выберите «Интерфейс инструмента», присвойте своему декоратору имя, например «MyDecorator». Это дает вам

public class MyDecorator implements MyInterfaceWithManyMethods {
    public void method1() {
    }
    public void method2() {
    }
    public void method3() {
    }
}

В новом классе выберите имя класса, затем «Refactor» -> «Заменить наследование делегированием», выберите интерфейс, отметьте все имена методов, нажмите ввод. Вы получите:

public class MyDecorator {

    private final MyObject object = new MyObject();

    public void method1() {
        object.method1();
    }

    public void method2() {
        object.method2();
    }

    public void method3() {
        object.method3();
    }

    private class MyObject implements MyInterfaceWithManyMethods {
        public void method1() {

        }

        public void method2() {

        }

        public void method3() {

        }
    }
}

Удалить внутренний класс и инициализатор объекта вручную. Вы получаете:

public class MyDecorator {


    public void method1() {
        object.method1();
    }

    public void method2() {
        object.method2();
    }

    public void method3() {
        object.method3();
    }

}

Нажмите Alt + Enter на «объекте», который теперь помечен красным, выберите «Создать поле», выберите MyInterfaceWithManyMethods.

public class MyDecorator {


    private MyInterfaceWithManyMethods object;

    public void method1() {
        object.method1();
    }

    public void method2() {
        object.method2();
    }

    public void method3() {
        object.method3();
    }

}

Выберите переменную объекта, нажмите Alt + Enter, выберите «Добавить параметр конструктора»:

public class MyDecorator {


    private MyInterfaceWithManyMethods object;

    public MyDecorator(MyInterfaceWithManyMethods object) {
        this.object = object;
    }

    public void method1() {
        object.method1();
    }

    public void method2() {
        object.method2();
    }

    public void method3() {
        object.method3();
    }

}

Вы видите, что все это делается несколькими нажатиями клавиш Alt + Enter. Читается как большая работа, но это может быть сделано менее чем за 20 секунд. Если у вас есть только 2 или 3 метода, вы можете работать быстрее с живым шаблоном, однако если у вас много методов со сложными сигнатурами, вы получите рабочий результат примерно через 20 секунд с этим методом. Alt + Enter просто качает: D

1 голос
/ 01 декабря 2010

Возможно, вы можете добавить шаблон файла, например:

class ${NAME} implements ${INTERFACE} {
   private final ${INTERFACE} delegate;

   public ${NAME}(final ${INTERFACE} delegate) {
       this.delegate = delegate;
}

, а затем, когда вы создали файл, используя этот шаблон, просто используйте Alt + Inser и выберите методы делегата.Это не идеально, но это может быть ярлык

...