Напористое программирование с JavaScript - PullRequest
12 голосов
/ 14 июля 2011

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

Например, этот код выдаст сообщение об ошибке и прервет пользователей.

function getDomainFromURL(url) {
    assertTrue(url, 'URL should not be null');

    ...parsing
}

Итак, я бы сделал так.

function getDomainFromURL(url) {
    if (!url) return;

    ...parsing
}

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

Вопрос 1 Вы так думаете?Или у вас есть другая идея?

Вопрос 2 Если вы так думаете, есть ли хороший способ сделать это с помощью Spring3 framework?

Ответы [ 6 ]

8 голосов
/ 14 июля 2011

Утверждения не должны использоваться для проверки любых вводимых пользователем данных. Их также не следует использовать для проверки ошибок. Assert - способ упростить отладку для программиста в случае неудачного тестирования. Также это способ облегчить понимание вашего кода.

Рассмотрим этот пример:

function calculateSomeCrazyFormula(a,b,c) {
    var d = a+b+c;
    ....
    k = (x + y)*2;

    assert(k != 0);
    l = d/k;        
    ....
    return x;
}

Моя формула по спецификации гарантирует , что k никогда не будет 0. Здесь я использовал assert почти как комментарий в своем коде. Это не подтверждает логику - это полностью противоположность. С утверждениями я проверяю правильность моей реализации этой сложной логики. Позже, когда я вернусь к своему коду и увижу l = d/k, я не буду подозревать, что происходит, когда k равно 0, потому что я вижу там свой assert и понимаю, что 0 никогда не должно произойти.

Кроме того, если где-то произошла ошибка и 0 действительно произошла, вы обычно увидите более глубокую ошибку. Например:

function otherFormula(a,b,c) {
    var x = calculateSomeCrazyFormula(a,b,c);

    var y = doSomeStuff(x);
    var z = doOtherStuff(y);
    return z;    
}

Без утверждений вы получите неверный результат этой функции. Вы не будете знать, почему вы получаете 0, когда оно должно быть 1. Вам нужно будет построчно отлаживать код и понимать, что пошло не так.

Однако с утверждениями вы сразу же заметите ошибку «утверждение не выполнено» и мгновенно сведете к минимуму область для поиска проблемы.

Утверждения полезны на любом языке программирования, включая Javascript, однако их не должно быть в среде Live. Поэтому, некоторые постпроцессорные системы должны удалять все утверждения из вашего кода перед выпуском.

4 голосов
/ 14 июля 2011

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

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

Лично я бы использовал первую форму везде, как в разработке, так и в производстве. Если утверждение не выполняется, вы получите очень полезные отзывы (в браузере, журналах и т. Д.) О причине вашей проблемы. Если вы удалите утверждение, у вас все равно будет ошибка, но будет сложнее отследить

Помимо

Этот стиль программирования - проверка предварительных условий - является частью того, что известно как контрактное программирование. Я никогда раньше не слышал о термине «напористое программирование».

2 голосов
/ 14 июля 2011

Всегда требуется условная обработка ошибок, когда вы работаете с асинхронными и управляемыми пользователем данными.Такое случается.Пользователи и сети облажались.Такова жизнь.Лучше всего иметь как минимум второй пример тогда и только тогда, когда разумно ожидать, что данные могут быть повреждены .Если вы несете ответственность за предоставление данных, которые вы тестируете, то вам необходимо перед тем, как вручить , что данные действительны.

Почему бы не иметь комбинацию:

function getDomainFromURL(url) {
    if( !assert( url != undefined, 'URL should not be null.' ) ) 
        return ''; 
    // '' is optional, but I don't like returning null if I expect a value.
    /* blah blah blah */
}

// as lightweight a function as you can have.
function assert( val, msg )
{
    if( !val )
    {
        console.log( msg );
        return false;
    }
    return true;
}

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

2 голосов
/ 14 июля 2011

Я не думаю, что хорошо иметь напористое программирование в Javascript по нескольким причинам:

  1. мне не нравится тот факт, что такая проверка ошибок должна выполняться в производственной среде,
  2. Люди специально для этой цели разработали инфраструктуру юнит-тестирования (JsUnit)
  3. этот оператор assert увеличивает размер кода, что увеличивает время загрузки и время выполнения.

Лучший способ сделать это - написать юнит-тесты.Таким образом, вы можете гарантировать, что ваш код не сломается при обновлении, а также это означает, что assert не появится в вашем рабочем коде.Конечно, вам может НУЖНО иметь такие вещи, как if (condition) error();, поскольку эти условия могут зависеть от пользователя, а не от разработчика.Это неизбежно, и вам нужно будет кодировать их вручную.

Правило большого пальца:

  • используйте if (condition) error();, когда условие зависит от пользователя
  • напишите юнит-тесты, если условие зависит от разработчика.

Наконец, с юнит-тестированием, вы можете проверить, правильно ли ваш код ошибки.Я не слишком уверен насчет JsUnit, но в ваших тестах вы могли бы сделать что-то подобное:

assertThrow(somefunc, args, YourError);

, чтобы согласиться с вашим if (condition) error(); в вашем коде

1 голос
/ 18 июля 2012

Вы можете использовать это так:

function getDomainFromURL(url) {
   assert(url != null, "url is null");
   if (!url) return;
    ...parsing
}

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

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

http://aymanh.com/9-javascript-tips-you-may-not-know/

1 голос
/ 14 июля 2011

Просто проигнорируйте это и сделайте их повторение, может быть лучше.

Тихая неудача не очень хорошая идея.С точки зрения удобства использования пользователи должны иметь немедленную обратную связь о своих действиях, даже в случае ошибок.Вы должны показать простую страницу с ошибкой, когда в вашем коде происходит что-то исключительное.Идея здесь такова: fail fast .

Я бы заставил вашу функцию assert перенаправить на страницу ошибки, если условие не выполнено, и занес бы ее в журнал.Вы можете сделать это в Javascript, установив window.location.href и зарегистрировать свою ошибку, написав с XHR .

...