2013-11-19 2 views
0

Я перерабатываю некоторый код, чтобы использовать полиморфизм, а не условные обозначения. Я хочу заменить два метода ниже на один, переопределенный метод, называемый «transferData», а затем два подкласса - «Uploader» и «Downloader» с «transferData» в качестве метода вызова.Рефакторинг для подклассов - как объединить методы экземпляра?

public class Example { 
    int direction; 
    public Example(int direction) { 
     this.direction = direction; 
    } 

    public void upload() {   
    } 

    public void download() {   
    } 
} 

Какой автоматический рефакторинг можно сделать, чтобы свести к минимуму количество ручных изменений, которые мне нужно выполнить? До сих пор у меня есть:

  • Введенный фабричный метод (с использованием автоматизированных средств рефакторинга в Eclipse)
  • создал «Downloader» подкласс и переопределить конструктор.

Каков наилучший способ обернуть эти вызовы методов, соответствующим образом обновив существующие сайты вызовов, не нарушив весь мой существующий код и тесты?

+0

Дайте как можно больше информации о вашем примере. Ваша проблема проста, как вы ее описываете? Всего 2 метода void без параметров, не влияющих на аргументы класса? – nelly

+0

Сложность больше в конструкторе - в настоящее время существует конструктор, который берет направление передачи. На сайтах вызовов вызывающий абонент вызывает вызовы .upload() или .download(), которые являются как недействительными, так и без аргументов. –

+0

Итак, для чего вам нужен инструмент рефакторинга? 'abstract class Example {... abstract void action();}, class Uploader {public void action() {}}, class Downloader {public void action() {}}' – nelly

ответ

1

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

Самый простой способ - сначала изменить родительский класс, чтобы использовать один метод transferData(), а затем использовать подклассы для разделения логики.

Шаг 1:

public class Example { 
    int direction; 
    public Example(int direction) { 
     this.direction = direction; 
    } 

    public void transferData(){ 
     if(direction>0){ 
      upload(); 
     }else{ 
      download(); 
     } 

    } 

    public void upload() {   
    } 

    public void download() {   
    } 
} 

Шаг 2: сделать upload() и download() больше не общественности. Измените клиентские вызовы для использования transferData().

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

public class Example { 
    ... 
    private void upload() {   

    } 

    private void download() { 

    } 
} 

Шаг 3: заменить все конструкции из примера с заводом. Снова для простоты вы можете сделать частный конструктор Example причиной ошибок компиляции, чтобы отслеживать все виды использования.

Шаг 4: Изменить фабрику, чтобы вместо этого возвращать подклассы.

Как только все скомпилировано, все тесты должны пройти.

Надеюсь, что это поможет.

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