2009-12-06 5 views
-1

Возьмите этот класс скелет, что кто-то хочет, чтобы заполнить, чтобы получать RSS потоки на ряд веб-сайтов:Логика проверки ценности внутри или вне класса?

public class RSSStream extends Thread { 

    public RSSStream(String rssStreamName,String rssURL,int refreshTime){ 
     // constructor code goes here 
    } 
} 

Теперь давайте рассмотрим, что RefreshTime должен быть выше нуля, и что rssURL должен быть действительным HTTP адрес.

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

Итак, вот несколько вопросов по этой теме:

  • Почему некоторые классы накладывают метод GetInstance(), связанный с тем, что, вероятно, является частным конструктор? Если я хорошо помню, примером может служить GregorianCalendar.
  • В каких случаях вы бы использовали такой же подход?
  • В большинстве случаев у вас есть логика проверки в вашем конструкторе?
  • Если да, примените ли вы это или нет к классам класса Entity, которые используются в контексте персистенции модели домена?

Все ваши ответы приветствуются. Будет интересно получить четкое представление о наиболее распространенной практике.

ответ

3

Некоторые из наиболее распространенных вещей:

  • Если вы используете FactoryMethod для строительства сложных объектов вы обычно имеют приватный конструктор и требует экземпляра через фабрику. Это поддерживает стратегии переключения на заводе.

  • Ясные мне бы бросить обычай (и, надеюсь, информативно) Exception в конструкторе, если конкретизации не может произойти::

    общественного класса Person {

    public Person(Integer id, String name) throws InvalidPersonException 
         if (name==null) throw new InvalidPersonException("You cant have a person without a name"); 
         ... 
    
  • Это, вероятно, создавать беспорядок в объектах сущности сущности, главным образом потому, что вы хотите, чтобы эти объекты были свободными от логики, и потому что инфраструктура должна обрабатывать это для вас - например если у вас есть bean-элемент, содержащий (id, name) в спящем режиме, и попытайтесь переместиться в таблицу с именем, которое должно быть не пустым, ошибка, которую должен выполнить db-бросок или из вашей конфигурации.

2

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

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

+0

Почему бы не выбрасывать исключение в конструкторе? –

2

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

getInstance() - это заводский метод, возвращающий экземпляр подкласса. Вы используете это, когда вы возвращаете другой подкласс в зависимости от обстоятельств. Например, Calendar.getInstance() возвращает GregorianCalendar в моей локали, но может возвращать другую реализацию, если мои настройки локали различны.

Для различных шаблонов для создания объектов, проверить http://en.wikipedia.org/wiki/Creational_pattern

Надеются, что это помогает

+0

Очень ясно и точно. Благодарю. –

2
  • я в основном видел и использовал статический getInstance() и закрытый конструктор только для использования шаблона Singleton. Однако абстрактный класс Java Calendar использует этот метод не для Singleton, а для создания экземпляра реализации по умолчанию (по-григориански) с часовым поясом по умолчанию и локали. Возможно, это делается потому, что Calendar является абстрактным и не может быть создан. GregorianCalendar фактически имеет публичные конструкторы.
  • В большинстве случаев я просто создавал методы конструктора и setter без аргументов, а также устанавливал логику проверки и бросание исключений в методах setter. Я часто использую инъекцию зависимостей Spring, а @Required annotation позволяет исключить контейнер, исключая все необходимые атрибуты.
  • Я не применяю подобную логику в объектах сущности, я стараюсь, чтобы для их простоты оставалась вся логика, и делала их строго ПОЖО.
+0

В ваших ответах много опыта. Большое спасибо за то, что вы делитесь своими знаниями. –

2

В этом конкретном случае я бы просто сделал проверку аргумента в конструкторе и выбросил исключение IllegalArgumentException с описательным сообщением об ошибке. Объект не будет создан, и код вызова должен быть восстановлен.

Вы можете сделать это и в методе getInstance(). Одной из причин использования getInstance() является то, что экземпляры очень совместимы, чтобы сократить количество создаваемых объектов. Например, если вы можете иметь несколько объектов RSSStream с тем же URL-адресом, вы можете настроить getInstance() для совместного использования этих экземпляров. (Это предполагает, что экземпляры являются неизменяемыми.)

Существует также шаблон Builder. Вы бы вложенную внутренний класс под названием RSSStream.Builder и говорят такие вещи, как:

RSSStream rss = new RSSStream.Builder.build(url) 
            .name("stack overflow") 
            .refreshTime(2) 
            .build(); 

Эта модель делает ваш код клиента более самостоятельной описательный, а также не гарантирует, что вы никогда не построить RSSStream в недопустимом состоянии (методами строитель выкинет IllegalArgumentException). Строитель достаточно гибкий, чтобы заменить всех ваших общественных конструкторов.

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

Вы можете использовать эти методы в своих классах моделей домена.

+0

В серьезном приложении я предполагаю, что количество подключений будет ограничено, поэтому обмен будет необходим. Я не очень хорошо разбирался в шаблоне строителя, поэтому этот пример очень ценится. Спасибо. –

2

Конструкторы, которым необходимо проверить свои аргументы, обычно вызывают IllegalArgumentException, если проверка не выполняется. Когда конструктор генерирует исключение, не нужно беспокоиться о «промежуточном инициализированном» объекте.

Смежные вопросы