Возможно, стоит рассмотреть использование статического метода фабрики вместо конструктора.
Я говорю вместо , но, очевидно, вы не можете заменить конструктор. Однако вы можете скрыть конструктор за статическим фабричным методом. Таким образом, мы публикуем метод статической фабрики как часть API класса, но в то же время скрываем конструктор, делая его закрытым или закрытым.
Это достаточно простое решение, особенно по сравнению с шаблоном Builder (как видно из Effective Java 2nd Edition Джошуа Блоха - будьте осторожны, Шаблоны проектирования Gang of Four определяют совершенно другое шаблон проектирования с тем же именем, что может немного запутать), что подразумевает создание вложенного класса, объекта-конструктора и т. д.
Этот подход добавляет дополнительный уровень абстракции между вами и вашим клиентом, укрепляя инкапсуляцию и облегчая изменения в будущем. Это также дает вам контроль экземпляра - поскольку объекты создаются внутри класса, вы, а не клиент сами решаете, когда и как эти объекты будут созданы.
Наконец, это облегчает тестирование - предоставляя тупой конструктор, который просто присваивает значения полям, не выполняя никакой логики или проверки, он позволяет вам ввести недопустимое состояние в вашу систему, чтобы проверить, как оно ведет себя и реагирует на это. , Вы не сможете сделать это, если проверяете данные в конструкторе.
Вы можете прочитать больше об этом в (уже упоминавшемся) книге Джошуа Блоха Effective Java 2nd Edition - это важный инструмент во всех инструментах разработчика, и неудивительно, что он является предметом 1-й главы книги. ; -) * 1 021 *
По вашему примеру:
public class Book {
private static final String DEFAULT_TITLE = "The Importance of Being Ernest";
private final String title;
private final String isbn;
private Book(String title, String isbn) {
this.title = title;
this.isbn = isbn;
}
public static Book createBook(String title, String isbn) {
return new Book(title, isbn);
}
public static Book createBookWithDefaultTitle(String isbn) {
return new Book(DEFAULT_TITLE, isbn);
}
...
}
Какой бы способ вы ни выбрали, хорошей практикой будет иметь один главный конструктор, который просто вслепую присваивает все значения, даже если он просто используется другими конструкторами.