Конструктор со всеми свойствами classа или конструктором по умолчанию с сеттерами?

Ниже приведены два подхода:

  • конструктор со всеми свойствами classа

Плюсы: мне нужно указать точное количество типов параметров, поэтому, если я сделаю ошибку, компилятор предупреждает меня (кстати, есть ли способ предотвратить проблему ошибочного переключения двух целых чисел в список параметров?)

Минусы: если у меня много свойств, строка создания может стать очень длинной, и она может охватывать две или несколько строк

  • сеттеры и пустой конструктор по умолчанию

Плюсы: я могу ясно видеть, что я устанавливаю, поэтому, если я что-то делаю неправильно, я могу точно определить его, как только я его набираю (я не могу сделать ошибку previuos при переключении двух переменных одного и того же типа)

Минусы: создание объекта с большим количеством свойств может занять несколько строк (не знаю, действительно ли это конфликт), и если я забуду установить свойство, компилятор ничего не скажет.

Что вы будете делать и почему? Вы знаете какой-либо световой шаблон (считайте, что он должен использоваться каждый раз, когда создается объект wth 7+)? Я спрашиваю об этом, потому что я склонен не любить большие конструкторы, где я не могу быстро найти, где находится переменная, которую я ищу, с другой стороны, я обнаружил, что «все свойства» уязвимы для отсутствия некоторых свойств.

Не стесняйтесь аргументировать свои предположения в плюсах и минусах, поскольку они – только мои мысли 🙂

Обновление – вопрос, который я нашел, связанный с этим: создание больших, неизменяемых объектов без использования конструкторов с длинными списками параметров

Вы можете взглянуть на шаблон Builder, предложенный Джошуа Блохом, и описанный в « Эффективной Java» . Есть презентация с основными моментами на http://developers.sun.com/learning/javaoneonline/2007/pdf/TS-2689.pdf ; без сомнения, вы могли бы найти лучшую ссылку.

В принципе, у вас есть другой class, возможно, внутренний class, который предоставляет методы, названные в честь установленных свойств, и которые возвращают исходный строитель, чтобы вы могли цеплять вызовы. Это делает довольно читаемый fragment кода.

Например, предположим, что у меня есть простое Message с несколькими свойствами. Созданный клиентский код может использовать построитель для подготовки Message следующим образом:

 Message message = new Message.Builder() .sender( new User( ... ) ) .recipient( new User( ... ) ) .subject( "Hello, world!" ) .text( messageText ) .build(); 

Фрагмент Message.Builder может выглядеть примерно так:

 public class Builder { private User sender = null; // Other properties public Builder sender( User sender ) { this.sender = sender; return this; } // Methods for other properties public Message build() { Message message = new Message(); message.setSender( sender ); // Set the other properties return message; } } 

Вы пропустили самый большой профессионал в создании конструктора с множеством параметров: он позволяет создавать неизменные типы.

Обычный способ создания неизменяемых типов без огромной конструкторской гадости – это иметь вспомогательный тип – строитель, который поддерживает значения, которые вам нужны в конечном объекте, а затем создает неизменяемый объект, когда вы будете готовы.

Недавние академические исследования (CMU и Microsoft) по удобству использования API говорят о том, что конструкторы по умолчанию с сеттерами будут способом использования в плане удобства использования. Это от «Юзабилити-последствий требуемых параметров в конструкторах объектов» Джефф Стилос и Стивена Кларка и был представлен на Международной конференции по разработке программного обеспечения:

Аннотация : удобство использования API-интерфейсов приобретает все большее значение для производительности программистов. Основываясь на опыте изучения юзабилити конкретных API, были изучены методы изучения удобства использования дизайна, характерного для многих API. Было проведено сравнительное исследование для оценки того, как профессиональные программисты используют API-интерфейсы с требуемыми параметрами в конструкторах объектов, а не без параметров «конструкторы по умолчанию». Было выдвинуто предположение, что требуемые параметры создадут более удобные и самодокументирующие API, направляя программистов на правильное использование объектов и предотвращая ошибки. Однако в исследовании было установлено, что, вопреки ожиданиям, программисты настоятельно предпочитают и более эффективны с API, которые не требуют параметров конструктора. Поведение участников анализировалось с использованием frameworks когнитивных измерений и выявления того, что требуемые параметры конструктора мешают общим страtagsям обучения, что вызывает нежелательные преждевременные обязательства.

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

Getters и seters значительно легче отлаживать, особенно если вы устанавливаете гарантии, которые вызывают исключение во время выполнения, если объект неправильно заполнен. И я большой поклонник «легко отлаживать».

До этого streamа я никогда не слышал о шаблоне Builder Роб. Никогда не использовал его сам (очевидно), но это чертовски интригующе.

Я предпочитаю принимать аргументы конструктора по вышеупомянутым причинам непреложности. Если это дает вам конструктор, который принимает много аргументов (скажем, более четырех или около того), это запах кода для меня: некоторые из этих аргументов должны быть объединены в свои собственные типы.

Например, если у вас есть что-то вроде этого:

 class Contact { public Contact(string firstName, string lastName, string phoneNumber, string street, string city, string state, int zipCode) { ... } } 

Я бы реорганизовал его так:

 class Contact { public Contact(Person person, PhoneNumber number, Address address) { ... } } class Person { public Person(string firstName, string lastName) { ... } } class PhoneNumber { public PhoneNumber(string digits) { ... } } class Address { public Address(string street, string city, string state, int zipCode) { ... } } 

Слишком большие classы – это действительно общая проблема дизайна в кодовых базах ООП.

Есть и другие аспекты. Если вы хотите иметь возможность выполнять определенные действия с вашим classом во время разработки, а не только во время выполнения, например, добавляя свой class в качестве объекта в палитре объектов (это Java с использованием Netbeans), вам необходимо предоставить конструктор без аргументов в чтобы иметь возможность сделать это.

Здесь есть и другие страtagsи. Прежде чем пытаться выяснить, как справляться с множеством параметров, я думаю, что важно пересмотреть свой дизайн и посмотреть, слишком ли много работает ваш class. Посмотрите, можете ли вы сгруппировать некоторые из параметров вместе в новый class и переместить некоторое поведение в этот class.

сеттеры и пустой конструктор по умолчанию

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

Кто сказал, что вы не можете обойти оба? Я бы сказал, что обязательные свойства входят в конструктор, а дополнительные – обработчиками. BTW, который говорит, что вам всегда нужен один сеттер на собственность? Если два свойства принадлежат вместе концептуально, почему бы не установить их вместе?

Мне тоже нравится шаблон Builder, но самое важное правило: всегда использовать свой мозг и находить дизайн, который наилучшим образом соответствует конкретной проблеме. Нет единого решения для всех.