Есть несколько тем, похожих на эту, но я не смог найти ни одной с достаточным ответом.
Я хотел бы знать, какова наилучшая практика перегрузки конструктора в Java. У меня уже есть свои мысли по этому поводу, но я хотел бы услышать больше советов.
Я имею в виду как перегрузку конструктора в простом классе, так и перегрузку конструктора при наследовании уже перегруженного класса (имеется в виду, что базовый класс имеет перегруженные конструкторы).
Спасибо :)
Переведено автоматически
Ответ 1
Пока нет "официальных рекомендаций", я следую принципу "ПОЦЕЛОВАТЬ и ВЫСУШИТЬ". Сделайте перегруженные конструкторы как можно более простыми, и самый простой способ заключается в том, чтобы они вызывали только this(...) . Таким образом, вам нужно будет проверять и обрабатывать параметры только один раз.
publicclassSimple {
publicSimple() { this(null); }
publicSimple(Resource r) { this(r, null); }
publicSimple(Resource r1, Resource r2) { // Guard statements, initialize resources or throw exceptions if // the resources are wrong if (r1 == null) { r1 = newResource(); } if (r2 == null) { r2 = newResource(); }
// do whatever with resources }
}
С точки зрения модульного тестирования протестировать класс станет проще, поскольку вы сможете вложить в него ресурсы. Если в классе много ресурсов (или соавторов, как называют это некоторые ОО-гики), рассмотрите одну из этих двух вещей:
Создайте класс параметров
publicclassSimpleParams { Resource r1; Resource r2; // Imagine there are setters and getters here but I'm too lazy // to write it out. you can make it the parameter class // "immutable" if you don't have setters and only set the // resources through the SimpleParams constructor }
Конструктору в Simple only либо нужно разделить SimpleParams параметр:
Да ... вы можете комбинировать оба способа в зависимости от того, что вам проще в данный момент. Классы параметров и простые заводские классы - это практически одно и то же, учитывая, что Simple класс использует их одинаково.
Ответ 2
Я думаю, что наилучшей практикой является наличие одного основного конструктора, на который перегруженные конструкторы ссылаются при вызове this() с соответствующими параметрами по умолчанию. Причина этого в том, что это намного проясняет, что такое сконструированное состояние объекта - на самом деле вы можете думать о первичном конструкторе как о единственном реальном конструкторе, остальные просто делегируют ему
Одним из примеров этого может быть JTable - основной конструктор принимает TableModel (плюс модели столбцов и выбора), а другие конструкторы вызывают этот основной конструктор.
Для подклассов, где в суперклассе уже есть перегруженные конструкторы, я бы склонен предположить, что разумно рассматривать любой из конструкторов родительского класса как основной, и думаю, что совершенно законно не иметь ни одного основного конструктора. Например, при расширении Exception я часто предоставляю 3 конструктора, один из которых принимает только String сообщение, другой принимает Throwable причину, а другой принимает оба. Каждый из этих конструкторов вызывает super напрямую.
Ответ 3
Если у вас очень сложный класс с большим количеством опций, из которых допустимы только некоторые комбинации, рассмотрите возможность использования конструктора. Очень хорошо работает как в программном, так и в логическом плане.
Конструктор - это вложенный класс с методами, предназначенными только для задания полей, и тогда конструктор ComplexClass принимает такой конструктор только в качестве аргумента.
Редактировать: конструктор ComplexClass может гарантировать, что состояние в конструкторе является допустимым. Это очень сложно сделать, если вы просто используете установщики в ComplexClass.
Ответ 4
Это действительно зависит от типа классов, поскольку не все классы созданы равными.
В качестве общего руководства я бы предложил 2 варианта:
Для классов значений и неизменяемых (Exception, Integer, DTO и подобных) Используйте единый первичный конструктор, как предложено в приведенном выше ответе
Для всего остального (сеансовые компоненты, сервисы, изменяемые объекты, сущности JPA и JAXB и так далее) Используйте только конструктор по умолчанию с разумными значениями по умолчанию для всех свойств, чтобы его можно было использовать без дополнительной настройки