Статьи

NetBeans 7.2: рефакторинг конструктора как статической фабрики

В публикации NetBeans 7.2: Рефакторинг параметризованного конструктора как построителя я рассмотрел, как NetBeans 7.2 поддерживает рефакторинг конструктора для построителя, как описано в пункте 2 второго издания эффективной Java . В этой статье я расскажу о том, как NetBeans 7.2 аналогичным образом поддерживает конструкторы рефакторинга для фабрик, как описано в пункте № 1 эффективной Java .

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

Employee.java с традиционным конструктором

package dustin.examples;

/**
 * Simple employee class intended to illustrate NetBeans 7.2 and refactoring
 * constructor to use Factory initializer as discussed in Item #1 of Joshua
 * Bloch's <em>Effective Java</em>.
 * 
 * @author Dustin
 */
public class Employee 
{
   private String lastName;

   private String middleName;

   private String firstName;

   private long id;

   private int birthYear;

   private int birthMonth;

   private int birthDate;

   private int hireYear;

   private int hireMonth;

   private int hireDate;

   public Employee(
      final String newLastName,
      final String newMiddleName,
      final String newFirstName,
      final long newId,
      final int newBirthYear,
      final int newBirthMonth,
      final int newBirthDate,
      final int newHireYear,
      final int newHireMonth,
      final int newHireDate)
   {
      this.lastName = newLastName;
      this.middleName = newMiddleName;
      this.firstName = newFirstName;
      this.id = newId;
      this.birthYear = newBirthYear;
      this.birthMonth = newBirthMonth;
      this.birthDate = newBirthDate;
      this.hireYear = newHireYear;
      this.hireMonth = newHireMonth;
      this.hireDate = newHireDate;
   }

   @Override
   public String toString()
   {
      return  this.firstName + " " + this.middleName + " " + this.lastName
            + " with ID " + this.id;
   }
}

Щелчок правой кнопкой мыши на конструкторе этого класса приводит к выбору рефакторинга, включая выделенный вариант «Заменить конструктор на Фабрика …»

Когда выбран вариант «Refactor: Replace Constructor with Factory …», появляется окно, подобное показанному на следующем снимке экрана. По умолчанию он имеет имя «создать» для фабричного метода.

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

Когда выбраны вышеупомянутые параметры, исходный код класса автоматически изменяется на код, показанный в следующем листинге кода. Обратите внимание, что конструктор изменен с открытого на закрытый, и генерируется новый метод newInstance.

Рефакторинг Employee.java (с ручными настройками пробелов)

package dustin.examples;

/**
 * Simple employee class intended to illustrate NetBeans 7.2 and refactoring
 * constructor to use Factory initializer as discussed in Item #1 of Joshua
 * Bloch's <em>Effective Java</em>.
 * 
 * @author Dustin
 */
public class Employee 
{
   public static Employee newInstance(
      final String newLastName, final String newMiddleName,
      final String newFirstName, final long newId,
      final int newBirthYear, final int newBirthMonth,
      final int newBirthDate, final int newHireYear,
      final int newHireMonth, final int newHireDate)
   {
      return new Employee(newLastName, newMiddleName, newFirstName,
                          newId, newBirthYear, newBirthMonth, newBirthDate,
                          newHireYear, newHireMonth, newHireDate);
   }
   private final String lastName;

   private final String middleName;

   private final String firstName;

   private final long id;

   private final int birthYear;

   private final int birthMonth;

   private final int birthDate;

   private final int hireYear;

   private final int hireMonth;

   private final int hireDate;

   private Employee(
      final String newLastName,
      final String newMiddleName,
      final String newFirstName,
      final long newId,
      final int newBirthYear,
      final int newBirthMonth,
      final int newBirthDate,
      final int newHireYear,
      final int newHireMonth,
      final int newHireDate)
   {
      this.lastName = newLastName;
      this.middleName = newMiddleName;
      this.firstName = newFirstName;
      this.id = newId;
      this.birthYear = newBirthYear;
      this.birthMonth = newBirthMonth;
      this.birthDate = newBirthDate;
      this.hireYear = newHireYear;
      this.hireMonth = newHireMonth;
      this.hireDate = newHireDate;
   }

   @Override
   public String toString()
   {
      return  this.firstName + " " + this.middleName + " " + this.lastName
            + " with ID " + this.id;
   }
}

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

Другие преимущества статического фабричного подхода к получению экземпляра и два недостатка этого подхода обсуждаются в пункте № 1 эффективной Java . В этом пункте делается вывод: «Часто статические фабрики предпочтительнее, поэтому избегайте рефлекса предоставлять публичные конструкторы без предварительного рассмотрения статических фабрик». NetBeans 7.2 позволяет легко увидеть, как конструктор может быть преобразован в статическую фабрику, и даже сделает основную работу для разработчика.