2009-10-30 2 views
3

У меня есть привычка всегда проверять средства определения свойств от плохих данных, даже если в моей программе нет места, которое могло бы разумно вводить плохие данные. Мой человек QA не хочет, чтобы я выбрасывал исключения, если я не могу объяснить, где они произойдут. Должен ли я проверять все свойства? Есть ли стандарт, на который я мог бы обратить внимание?Вопрос о создании ООП - Проверяющие свойства

Пример:

public void setName(String newName){ 
    if (newName == null){ 
     throw new IllegalArgumentException("Name cannot be null"); 
    } 
    name = newName; 
} 

... 

//Only call to setName(String) 
t.setName("Jim"); 
+1

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

+0

Единичное тестирование? Мы не нуждаемся ни в одном модульном тестировании ... (я знаю, я знаю, но я не могу все изменить ...) –

ответ

4

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

1

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

0

Это компромисс. Это больше кода для написания, просмотра и обслуживания, но вы, вероятно, быстрее найдете проблемы, если каким-то образом получится нулевое имя.

Я наклоняюсь к нему, потому что в конце концов вы находите, что вам это нужно.

Раньше у меня были классы полезности, чтобы свести код к минимуму. Таким образом, вместо

if (name == null) { throw new ... 

вы могли бы

Util.assertNotNull(name) 

Затем Java добавил утверждает на язык, и вы могли бы сделать это более непосредственно. И выключите его, если хотите.

2

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

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

0

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

1

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

0

Я не знаю ни одного документально подтвержденного стандарта, который гласит: «Проверяйте все входные данные пользователя», но это очень хорошая идея. В текущей версии программы может оказаться невозможным получить доступ к этому конкретному свойству с недопустимыми данными, но это не помешает ему в будущем. Во время технического обслуживания происходят всевозможные интересные вещи. И эй, вы никогда не знаете, когда кто-то будет повторно использовать класс в другом приложении, которое не проверяет данные перед его передачей.

1

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

Используя конкретный пример, который вы отправили, IMHO вы должны выполнить проверку, но по-другому.

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

Предположим, вам нужно добавить эти правила проверки: если вы придерживаетесь своего подхода, вы в конце концов загромождите своего сеттера, как сказал @SingleShot.

Кроме того, что бы вы сделали, если более одного объекта домена имеет setName setter? Даже если вы используете классы-помощники как @dave, код все равно будет дублироваться: вызывает экземпляры помощника.

Теперь подумайте: что, если все аргументы, которые вы могли бы получить в методе setName, были действительны? Разумеется, проверка не требуется. Я могу показаться слишком оптимистичным, но это можно сделать.

Помните, что вы имеете дело с именами, так почему бы не моделировать концепцию имени? Вот ваниль, фиктивная реализация показать идею:

public class Name 

    public static Name From(String value) { 
    if (string.IsNullOrEmpty(value)) throw new ... 
    if (value.contains(' ')) throw new ... 

    return new Name(value); 
    } 

    private Name(string value) { 
    this.value = value; 
    } 

    // other Name stuff goes here... 
} 

Поскольку проверка происходит в момент создания, вы можете получить только действительные случаи Имени. Невозможно создать экземпляр Name из строки «invalid». Не только централизованно проверен код проверки, но и исключения выбрасываются в контексте, который имеет для них значение (создание экземпляра имени).

Вы можете ознакомиться с замечательными принципами дизайна в «Принципах дизайна позади Патагонии» Эрнана Уилкинсона (пример с примера взято из него). Обязательно проверьте ESUG 2010 Video и presentation slides

Наконец-то, я думаю, вы можете найти статью "Fail Fast" Джима Шора.

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