Программирование


Объявление переменных

Забудьте о том, чему вас учили в университетах. Нельзя объявлять переменные с именами x1 или name. Ведь не пишут на пакете с молоком название "тмл1546". Именования переменных должны нести смысловую нагрузку. Например, если это сумма транзакций, то неверно будет обозначить переменную sum_tr, не поленитесь полностью написать SumTransactions или TransactAmont. То же самое касается объявления функций. Если функция имеет назначение "получить сумму положительных транзакций", то объявление должно иметь соответствующее именование ReturnSumTransactionsByAdditive.

Названия классов обычно начинаются с символа С, 2й символ также является заглавным, следуя принципу именования, приведённому выше, это довольно устоявшийся стиль, не стоим им пренебрегать. (CArticle, CCalculator). Стоит добавить, что при разработке ПО мы почти всегда используем готовые классы, то рекомендуется добавлять постфикс, чтобы отличать внутренние разработанные классы и "внешнее ПО". (CArticleDQuad, CCalculatorDQuad).

Методы и свойства объектов. Чтобы отличать внутренние функции и переменные для переменных желательно добавлять префикс “_”. $Article->_Announce (свойство объекта), $Article->CheckAnnounce(функция).

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

Пример: если у вас есть таблица свойств объекта, в которой первичным ключём является обычно ID, т.е. при вызове процедур вы используете идентификаторы свойств (10/*автор */,11/* тема */,12/* рейтинг */), будет правильным вынести в отдельный файл.

define("IBLOCK_PORTFOLIO", 38); define("IBLOCK_MODULES", 42); define("IBLOCK_VACABULARY", 43);

При написании кода обязательно используются переменные, которые необходимы для построения логики и переменные, которые требуется вывести в конечном результате. Предлагается использовать для первых нижний регистр, а для вторых ВЕРХНИЙ. Например, $TmpText и $FINAL_TEXT.

Документирование и комментирование кода

На мой личный взгляд документирование кода является САМОЙ важной частью при написании программ. Потому как ПО без документации – мёртвоё ПО.

Документирование программы состоит из 3х частей.

  1. Постановка задачи (заказчик, заинтересованное лицо)
  2. Проектирование (перевод задачи в понятный и конкретный вид для программиста)
  3. Документация кода (сопровождение комментариями программного текста)

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

  1. требуется сделать вывод левого меню для информационного блока "Статьи", используя в качестве пунктов разделы (секции/группы)
  2. поскольку уже имеется готовый механизм для работы с меню, класс CMenu, который работает со следующей структурой

Array(

НАЗВАНИЕ_ПУНКТА,
ССЫЛКА,
дополнительные пункты для подсветки,
МАССИВ ПАРАМЕТРОВ,
УСЛОВИЕ, КОТОРОЕ СЛЕДУЕТ УЧИТЫВАТЬ ПРИ ВЫВОДЕ
)
требуется организовать вывод статей, хранящихся в БД и параллельно передать на вход CMenu аналогичную структуру массива

НАЗВАНИЕ ПУНКТА – название раздела
ССЫЛКА – страница вывода статей с передачей параметра, ID
УСЛОВИЕ, КОТОРОЕ СЛЕДУЕТ УЧИТЫВАТЬ ПРИ ВЫВОДЕ – для информационного блока создать дополнительное свойство PRP_SHOW, которое учитывать при выводе меню

3) непосредственно код

  1. <?php
  2. /*
  3.  строим рекурсивно дерево разделов и элементов
  4.  используем параметры для построения, как у Битрикс (типичный пункт меню)
  5.  Array(
  6.   "Только для администраторов" -НАЗВАНИЕ/catalog/admin/", - ССЫЛКА
  7.   Array("/catalog/admin/index.php", "/catalog/admin/edit.php"), - дополнительные пункты для подсветки
  8.   Array("PARAM_1" => "Y"), - МАССИВ ПАРАМЕТРОВ "\$GLOBALS["USER"]->IsAdmin()" - УСЛОВИЕ, КОТОРОЕ СЛЕДУЕТ УЧИТЫВАТЬ ПРИ ВЫВОДЕ )
  9.  после чего вызывается функция
  10.  if(!$this->RecalcMenu()) //переводит массивы в новую //структуру для обработки
  11.   return false;
  12.   // $TEXT - текст меню
  13.  // $LINK - ссылка меню
  14.  // $SELECTED - выбрано ли меню в данный момент
  15.  // $PERMISSION - доступ на страницу указанную в $LINKS
  16.  // $ADDITIONAL_LINKS - дополнительные ссылки для подсветки меню
  17.  // $ITEM_TYPE - "D" - если $LINKS заканчивается на "/" (директория), "P"
  18.  //- иначе (страница)
  19.  // $ITEM_INDEX - порядковый номер пункта меню
  20.  // $PARAMS - параметры пунктов меню
  21. */
  22. function ListSectionToMenuAr($SECT_ID/* ID секции, для которой требуется построить меню*/,$IBLOCK/* инфоблок - обязателен */)
  23. {
  24. //получим пока НАЗВАНИЕ ПУНКТА и ССЫЛКУ, остальные 3 параметра пока //будут пустые
  25. //---------формирование выходного массива
  26. $items = GetIBlockSectionList($IBLOCK, $SECT_ID,
  27. Array("sort"=>"asc"), 0);
  28. while ($local=$items->GetNext())
  29. {
  30. $MASSIVE[]=Array(
  31. $local["NAME"],
  32. $local["SECTION_PAGE_URL"],
  33. Array(),
  34. Array(),
  35. ""
  36. );
  37. }
  38. //***------формирование выходного массива
  39. return $MASSIVE;
  40. }
  41. ?>
  42.  

Отметим несколько тезисов по документации кода

  • при описании процедуры описываем контекст вызова функции
  • все входные параметры имеют описание
  • в самой функции документируются только логические блоки (в нашем случае он только 1)
  • логические блоки оформляются визуально рамками

//-----ОПИСАНИЕ [обозначает начало],
//***---ОПИСАНИЕ [обозначает конец логического блока]

Принцип ООП

Что такое "объектно-ориентированный" подход? Он подразумевают, что какая-то деятельность направлена на определенный объект. Объектами в жизни выступают все окружающие нас предметы: автомобили, книги, стол, часы.

Рассмотрим такой объект, как телевизор. Внутри этого объекта находятся множество других объектов: микросхемы, провода, электронно-лучевая трубка и так далее. Но при взаимодействии с телевизором мы об этом даже и не задумываемся. В этом заключается первый принцип ООП - инкапсуляция. Инкапсуляция тесно связана со вторым принципом - абстракцией, без которой не возможно сокрытие кода.

Мы также знаем, что, нажав на определенную кнопку, мы включим телевизор, а удерживая другую - увеличим или уменьшим громкость. При этом от объекта мы получаем только результат его работы, не задумываясь о его внутренних процессах. Это составляет второй принцип - абстракцию. Если немного углубиться, то с помощью абстракции создаются шаблоны для управления объектами. Очень простой пример – очень часто в жизни вы встречаетесь с плюсом и минусом. Причём вы чётко знаете что произойдёт с объектом, если вы примените то или другое действие. В нашем примере это была громкость. Но сколько разных объектов подвержены этим же операциям. Будь то оценка в школе, полярность тока, сложение в математике, понижение и повышение температуры. “+” и “-” это и есть шаблонные операции.

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

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

MVC (Модель-представление-контроллер)

Стандартная схема архитектуры «Модель-Вид-Контроллер» изображена на следующем рисунке: (схема заимствована из книги «Ajax in action» издательского дома «Вильямс»)

Схема архитектуры MVC Схема архитектуры MVC

Разберём по пунктам данную схему.

В шаблоне MVC, как следует из названия, есть три основных компонента: Модель, Представление, и Контроллер.

Представление (вид) отвечает за отображение информации, поступающей из системы или в систему.

Модель является «сутью» системы и отвечает за непосредственные алгоритмы, расчёты и тому подобное внутреннее устройство системы.

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

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

Итак, условимся:

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

Контроллер. Модуль управления вводом и выводом данных. Данный модуль должен следить за переданными в систему данными (через форму, строку запроса, cookie или любым другим способом) и на основе введённых данных решить:

· Передавать ли их в модель

· Вывести сообщение об ошибке и запросить повторный ввод (заставить модуль представление обновить страницу с учётом изменившихся условий)

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

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

Проще говоря – разделяйте логику и шаблонизаторы.

Принцип DRY (Don’t Repeat Yourself)

Этот принцип лежит в основе любой оптимизации кода. Для этого были придуманы циклы, процедуры, функции. Данный пункт не требует пояснения, основной постулат здесь “не используйте copy-paste”.