[Закрыть]
 
popoff.donetsk.ua
Чем занимаются птички на улице?
Начало | Новости | Статьи | Форум | Опросы | Карта сайта | Обо мне
popoff.donetsk.ua - Статьи - Программирование - Технологии программирования - Что считать ошибкой?
Я это делаю
Персональное меню
Голосование
Деньги, либо любимое занятие? Постоянный адрес этого вопроса
Деньги, но неинтересная работа и невозможность уделить время семье
Интересная работа, возможность саморазвиваться, но нищенский заработок
Ваш возраст (не обязательно)
Почему? (не обязательно)

Голосование закрыто.

Поиск по сайту
Реклама
Программное обеспечение любой сложности
koins.com.ua
Статистика

Что считать ошибкой?

Постоянный адрес статьи

Пользователи и программисты

Я мог бы выделить два подхода, которым пользуются программисты при создании программ:

  1. подход, ориентированный на пользователя

  2. подход, ориентированный на программиста

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

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

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

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

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

Достоинства подхода, ориентированного на пользователя (почему нужно пользоваться этим подходом):

  • <p> C точки зрения пользователя это самый естественный подход: большинству пользователей совершенно все равно, как программа устроена внутри, их интересует только вход и выход. Поскольку программы пишутся для пользователей, а не для программистов, то и подходить к созданию программ нужно так, чтобы в первую очередь нас интересовал вход и выход. </p><p> Некоторые могут возразить: «Да, но для нас, как для программистов, тоже иногда пишутся программы. Взять, например, компилятор Delphi - он не для пользователей, он для программистов; для тех, кто ПРОГРАММИРУЕТ.». </p><p> На это я мог бы сказать, что с точки зрения компилятора Delphi мы, программисты, являемся пользователями. Мы ПОЛЬЗУЕМСЯ этим компилятором. Для нас, как для пользователей, важно, что на вход мы подаем исходный текст, а на выходе мы получаем откомпилированный вариант. Для нас важно удобное меню, кнопочки, «украшения» и т.п. И при этом нам все равно, каким именно способом Delphi компилирует наши программы. Для нас важен ТОЛЬКО вход и выход: они должны быть такими-то и такими-то. </p>

Недостатки подхода, ориентированного на пользователя (почему этим подходом пользоваться не выгодно):

  • <p> Сопровождать программу, написанную программистом, который концентрировался только на входе/выходе и при этом не задумывался о внутреннем устройстве - это гиблое дело. Проще все написать заново. </p>
  • <p> Зачастую функции, которые хотели бы видеть пользователи, очень сложно реализуемы или даже вообще не реализуемы. </p>
  • <p> Если думать только о пользователе, то на написание любой программы можно потратить любое, неограниченное сверху количество времени. Это связано с неограниченностью количества функций, которые могут понадобиться пользователям. </p>

Достоинства подхода, ориентированного на программиста (почему нужно пользоваться этим подходом):

  • <p> С точки зрения программиста это самый естественный подход. В целом, можно сказать, что не возможно написать правильно работающую программу и при этом не понимать, как она устроена внутри. </p><p> Если Вы написали правильно работающую программу и при этом не до конца понимаете, почему она работает именно так, как работает, то следует ожидать ошибок в этой программе. Скорее всего, она работает правильно лишь на Ваших контрольных примерах. </p>

Недостатки подхода, ориентированного на программиста (почему этим подходом пользоваться не выгодно):

  • <p> Как ни парадоксально это звучит, но недостаток ориентации на программиста состоит в отсутствии (или недостаточной) ориентации на пользователя. Этот недостаток ярко выражается фразой: </p><p> Десять минут головной боли одного программиста может стоить многих лет головной боли миллионов пользователей. </p><p> Ориентируясь на себя, думая о том, как бы решить эту задачу попроще да побыстрее, мы забываем о пользователях. </p><p> Программами, написанными программистами, ориентированными на себя, не возможно пользоваться. Эти программы делают то, что удобно было запрограммировать, а не то, что нужно пользователю. </p>

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

У новичков это может выражаться в фразах типа «на контрольном примере работает» или «я не знаю, как это реализовать». У программистов с опытом это может выразиться в фразе типа «так проще реализовать».

О новичках я не буду говорить - с ними все просто - им нужно набираться опыта. А вот программистов с опытом хочется прокомментировать. Часто оказывается (именно «часто», а не «всегда»!), что под фразой «так проще реализовать» кроется тот факт, что сам программист не слишком хорошо продумал внутреннее устройство своей системы и теперь, чтобы «реализовать по-другому», ему нужно рефракторить (улучшать) свой старый код. Если забыть о пользователе, то вполне можно отказаться от рефракторинга, отмахнувшись фразой типа «пользователю эта функция не нужна».

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

Что считать ошибкой?

Теперь, когда мы знаем о двух подходах к «смотрению» на программы, мы можем поискать ответ на вопрос «Что считать ошибкой?».

Часто оказывается, что ошибка - это не объективная реальность, а скорее субъективное восприятие, зависящее от того, с какой стороны мы смотрим на программу.

Например, считать ли предупреждения ошибками?

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

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

Здесь хотелось бы отметить примечательный факт: почему некоторые склонны подавлять предупреждения? Эффект страуса нам в этом поможет: если предупреждения не видно, значит его нет. А когда в написанной тобой программе нет ни ошибок, ни предупреждений, как-то становится легче на душе. Любовь к сладкой лжи даже здесь вылезла.

Итак, предупреждение - это ошибка? Формально - нет. Фактически - да. Какой ответ Вам больше нравится - выбирайте любой!

Другой пример: Соответствует спецификации, но результат не такой, как ожидается. Где ошибка?.

Обычно этот вопрос возникает при стыковке двух программ.

Например, есть спецификация языка HTML, в которой написано, что теги <td>, <tr>, <li> и т.п. могут быть не закрыты - следующие за ними другие теги автоматически закрывают эти теги.

Мы, программисты, пользуясь этой спецификацией, пишем html-код, в котором оставляем не закрытый тег <td>, например. И тут, откуда ни возьмись, возникает пользователь с допотопным браузером, в котором некорректно учтена спецификация и незакрытые теги <td> приводят к некорректному отображению всего документа. Где ошибка?

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

Совсем иначе обстоят дела, если смотреть с точки зрения пользователя. Он, пользователь, пользуется этим браузером довольно давно и большинство посещаемых им сайтов отображается правильно (если бы большинство сайтов отображались не правильно, то он давно сменил бы браузер), а наш сайт - не правильно. Какой нормальный пользователь сделает вывод о глючности браузера? Большинство подумают, что это на нашем сайте ошибка.

Я склонен согласиться с пользователем, потому что закрытый тег <td> не является ошибкой с точки зрения спецификации, но при этом отображается правильно в большем количестве браузеров. Почему мы оставили тег <td> открытым, хотя могли бы и закрыть - останется загадкой для всех.

Итак, наш код соответствует спецификации, но не правильно отображается в каком-то браузере. Где ошибка? Формально - в браузере, потому что это в нем не корректно реализована спецификация. Фактически - в нашем коде, потому что мы не тестировали наш код под этим браузером.

Составление спецификации: ориентация на программиста или на пользователя?

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

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

Например, упомянутая выше спецификация HTML. Очень удобно для пользователя иметь возможность не закрывать теги, не ставить кавычки и т.п.

Другой пример - любимый мною язык PHP. Очень удобно для пользователя, когда переменные из _GET, _POST, _COOKIE сразу доступны как обычные переменные (при включенном register globals). Если в этих переменных передать строку с кавычкой, а потом эту строку без преобразований подставить в SQL-запрос, то можно выполнить атаку SQL-Injection. Как с этим бороться? Очень просто - пользователю было бы очень удобно, если бы перед кавычками автоматически вставлялись слеши. Или, вот еще одно «удобство»: если строка соответствует правилам составления имен в PHP и константа с таким именем не определена, то эту строку можно не заключать в кавычки. В целом, интерполяция строк мне тоже видится такого рода «украшением» - она введена для удобства пользователя, но никак не из насущной необходимости.

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

Удобства от этих «украшений», конечно, есть. Хотя и в сомнительных количествах. А вот при ближайшем рассмотрении головной боли они прибавляют в ощутимых количествах.

Я перечислил здесь эти особенности для того, чтобы найти ответ на следующий вопрос:

Вольности в спецификации - это ошибка?

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

Вот здесь хотелось бы обратить внимание на одно несоответствие: спецификации нужны для того, чтобы одни программисты могли договориться с другими программистами. Какое отношение к программистам имеет точка зрения пользователя - не совсем ясно. А ведь говоря об «украшениях» мы говорили именно с точки зрения пользователя: пользователю так удобнее.

Итак, считать ли вольности в спецификации ошибкой? Формально - нет, потому что спецификация может быть в принципе любой. Фактически - да. История нам уже показала, к чему приводят вольности в спецификациях.

Теперь мы готовы ответить на главный вопрос:

Неправильный результат работы программы - это ошибка?

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

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

А вот с точки зрения пользователя поставленный вопрос просто не имеет смысла. Я думаю, все знают, почему.

К чему я это все?

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

Десять минут головной боли одного программиста может стоить многих лет головной боли миллионов пользователей.

Юрий Попов, popoff.donetsk.ua

Последняя модификация: 22.12.05 02:58

Обсуждение статьи в форуме

Не проходите мимо! Оставьте Ваш комментарий в форуме! >>>

12.10.06 23:13 MaxKorsak

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

Спасибо за ответ,
с уважением mr_max

16.10.06 16:22 WP

Notice нужно включить :)

Просмотреть все комментарии в режиме форума. Всего комментариев: 2
Не проходите мимо! Оставьте Ваш комментарий в форуме! >>>