Книга знаний

Инф. технологии / Приемы программирования / Встроенный язык

Признаки плохого программирования

Рассмотрены признаки плохого программированияАвтор статьи: Гений 1С | Редакторы: Волшебник, Fynjy, Лёвыч, EmK, Stillcat,
Последняя редакция №13 от 25.12.06 | История
URL: http://kb.mista.ru/article.php?id=273

Ключевые слова: программирование, стиль, оформление


Функции с большим числом параметров


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

Пример плохого стиля:
ПеретаскиваниеВНовуюОбластьДанных(Элемент, ПараметрыПеретаскивания, СтандартнаяОбработка, Строка, Колонка, ПраваДоступаПользователей, МодифицированностьФормы)


Использование в коде программы конкретных данных


Пример плохого стиля:
Если ИмяПользователя="Иванов_С" Тогда ... КонецЕсли

Представьте потом, что если пользователь уволится, нужно будет найти все случаи, где встречается Иванов_С и сделать замену на нового сотрудника.
Пример плохого стиля:
Если Справочник.Код=17 Тогда ... КонецЕсли

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

Использование глобальных переменных


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

Дублирование кода


Весь дублирующийся функционал нужно выносить в процедуры и функции:
Сравните:
А=Макс(Х,-Х);
Б=Мин(Y,-Y);

Против:
А=Модуль(Х);
Б=-Модуль(Y);


Замена индекса массива кодом


В коде начинающих программистов часто встречаются конструкции вида:
А1=0;
А2=0;
А3=0;
А4=0;
А5=0;

Против:
Для Каждого Эл из А Цикл
    Эл=0;
КонецЦикла;

На самом деле примеры бывают ужаснее (по 100, 200 элементов), просто нет под рукой ссылок.

Имена переменных, процедур и функций

Система именования переменных



Часто очень приходиться разбирать чужой код. И очень многие забывают о том, что после них будут работать другие люди и читаемость кода зависит от того какие имена переменным, процедурам и функциям мы даем.
Начинающие в большинстве (из-за лени) дают вот таки имена:
Не правильно.
А1, А2
Эл, Пр, Спр, Док

Из-за этого код становиться сложно читаемым.
Правильно
Без локализации.
Счетчик, СправочникКонтрагенты

С локализацией.
//гл - глобальная, ф - форма, м - общая модуль, л - локальная процедура/функция, сз - список значений и т.д. 
лСчетчик, мСправочникКонтрагенты, лсзСправочникТМЦ

Более детально можно почитать в любой книге по программированию + на ИТС достаточно подробно описаны данные правила (дайте пожалуйста название темы на ИТС, не нашли - ИТС - > 1C:Система стандартов и методик разработки конфигураций - общие правила построения метаданных - Оформление модулей).

Еще можно почитать здесь: Книга знаний: Kazakh Notation (Казахская нотация) В программировании это называется "венгерская нотация".

Похожие имена


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

Мат


Не рекомендуется использовать в комментариях, названиях переменных и т.п. мат.
Особенно не рекомендуется использовать его в процессе отладки.
Был случай, когда программист в отладочной базе отлаживался под пользователем "Пиздюков Фома Ильич", но он не знал, что извещения о проведении документов в некоторых случаях отсылаются на рабочие e-mail руководителей. В результате был неприятный скандал.

Явное объявление локальных переменных


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

Использование текущей даты в функциях


Иногда встречаешь код, где внутри функции используется вызов ТекущаяДата().
Во-первых это нарушает изолированность функции, т.к. используются данные, которые не передаются в
фунцию.
А во-вторых это лишает нас возможности получить результаты функции на указанную дату, а часто если вначале такое и не нужно, то потом требуется. Пример из жизни: функция вычисляла на текущую дату накопленную сумму покупок покупателями для расчета текущего рейтинга. А затем понадобилось узнать, какая сумма была накоплена на дату Х, чтобы проверить, правильно ли был рассчитан рейтинг. Пришлось переделывать функцию.

Прочее


Напишите здесь ваши мысли.

// + {{ Лёвыч

Использование методов Сообщить(), Предупреждение(), Вопрос() и прочих модальных окон


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

  • Всегда указывайте не нулевой таймаут при вызове функций типа Вопрос() и Предупреждение(), чтобы порождаемые ими модальные окна закрывались самостоятельно в случае, если пользователь куда-нибудь отошел от компьютера
  • Глобальные процедуры и функции не должны ни чего сообщать, спрашивать или о чем-то предупреждать. Всевозможные описания ошибок следует передавать в специальный необязательный параметр. Например:
    Процедура глСканерШК_ЗагрузитьДрайвер() Экспорт
    
       Если ЗагрузитьВнешнююКомпоненту("ScanOPOS.DLL")<>0 Тогда            
         Scan = СоздатьОбъект("AddIn.Scanner");   
       Иначе   
          Предупреждение("Ошибка загрузки драйверов сканера: ScanOPOS.DLL!");
       КонецЕсли;
    
    КонецПроцедуры

    Это нельзя назвать адекватным программированием, поскольку, если эта процедура удет вызвана из ПриНачалеРаботыСистемы(), то в случае отсутствия Scanopos.dll в каталоге базы нельзя будет загрузить эту базу в режиме предприятия программно. Например для обмена по ОЛЕ или с целью реализации какого-то автопроцесса. Куда логичнее изменить эту процедуру таким образом:
    Функция глСканерШК_ЗагрузитьДрайвер(сОписаниеОшибки = "") Экспорт
       
       Если ЗагрузитьВнешнююКомпоненту("ScanOPOS.DLL")<>0 Тогда            
         Scan = СоздатьОбъект("AddIn.Scanner");   
       Иначе   
          сОписаниеОшибки = "Ошибка загрузки драйверов сканера: ScanOPOS.DLL !";
          Возврат 0;
       КонецЕсли;
       
       Возврат 1;
    
    КонецФункции

    Таким образом, глобальные методы должны выполнять некоторые операции, а обработкой ошибок должен заниматься тот, кто эти методы вызвал
  • В обработке проведения документов недопустимы ни какие Предупреждения, Вопросы и прочие модальные окна, иначе восстановление последовательности документов, а равно как и любое программное проведение документов, будет очень трудоемким или вообще невозможным процессом

  • Для оживлния долгоиграющих процесов предпочтительнее использовать процедуру Состояние(), нежели Сообщить() иначе, опять-таки, пользователи перестанут обращать внимание на все сообщения, в том числе и на критичные


Некорректность и неоднозначность именования процедур и функций


Процедура/функция должна делать именно то, что написано в ее названии. Напрмер, пусть у нас есть некая база данных, в которой реализоаны статусы документов для целей контроля жизненного цикла документов. Вот такой код нельзя назвать адекватным:
Процедура ДокументРасходная_УстановитьСостояние(докРасходная, СостояниеДокумента)
   
   // блок, устанавливающий состояние расходной

   // а вот тут совершенно неожиданный блок, устанавливающий
   // состояния некоторых (не всех) подчиненных данной
   // расходой документов
   
КонецПроцедуры

Тут проблема в том, что понимать код или/и корректировать, написаный подобным образом, крайне трудно, а порой и не возможно - легче все переписать заново.
// }} Лёвыч


Описание | Рубрикатор | Поиск | ТелепатБот | Захваченные статьи | Установки | Форум
© Станислав Митичкин (Волшебник), 2005-2025 | Mista.ru

Яндекс.Метрика