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

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

Новые методы теперь доступны для любого кода класса Customer. Их можно очень просто вынести в интерфейс класса, доступный другим частям системы, требующим эту информацию. Без подобных методов, другим методам класса придется заботиться о заказах клиента и строить свои собственные циклы. Это усложняет систему, что приводит к увеличению объема кода для разработки и поддержки.

Вы можете немедленно почувствовать разницу на примере htmlStatement. Теперь я могу отложить рифэкторинг и наконец добавить новый метод. Мoжно написать htmlStatement и добавить соответствующие тесты.

  public String htmlStatement() {
    Enumeration rentals = this.rentals.elements();
    String result = "<h1>Rentals for <em>"+getName()+"</em></h1><p>\n";
    while( rentals.hasMoreElements()) {
      Rental each = ( Rental) rentals.nextElement();

      // show figures for this rental
      result += "\t"+each.getMovie().getTitle()+": "+
                String.valueOf( each.getCharge())+"<br>\n";
    }

    // add footer lines
    result += "You owe <em>"+String.valueOf( getTotalCharge())+"</em><p>\n";
    result += "On this rental you earned <em>"+
              String.valueOf( getTotalFrequentRenterPoints())+
              "</em> frequent renter points<p>";

    return result;
  }
После вынесения расчета итогов, можно написать метод htmlStatement, повторно использовав тот же код для расчета итогов, что и в методе statement. Причем это не копирование и вставка, так что если правила расчета изменятся, то исправления придется вносить только в одном месте. Кроме этого оказывается возможным быстрая и простая подготовка любых других типов отчета. Рифэкторинг занял не так уж много времени, большая часть которого была потрачена на то, чтобы понять, как работает существующий код, но это пришлось бы делать в любом случае.

Некоторая часть кода была скопирована из текстового варианта отчета, главным образом инициализация цикла. Один из возможных дальнейших путей продолжения рифэкторинга - это вынесение методов для подготовки заголовка, детальной строки и подвала отчета. Вы можете увидеть как это сделать в примере для рифэкторинга Form Template Method (345). Но сейчас пользователи снова шумно требуют новых изменений. Они почти готовы как измененению классификации фильмов. До сих пор еще не понятно, какие именно изменения они хотят внести, но похоже, что будет предложена новая классификация на замену существующей. Будет решен вопрос с расчетом задолженности и бонуса. Но на настоящий момент подобные изменения вносить затруднительно. Потребуется менять методы для расчета задолженности и бонуса и править условную логику, связанную с класификацией фильмов.


В начало | предыдущая | следующая