От автора: Читаемость кода – универсальный предмет в мире компьютерного программирования. Это – самое первое, о чем мы узнаем в качестве разработчиков. Читаемый и легко поддерживаемый код в законченном продукте – это нечто, чем можно гордиться. Им можно поделиться с друзьями, внести в другие проекты, использовать снова и снова из приложений, которые были написаны месяцы и даже годы назад.
В этой статье детально описаны пятнадцать самых важных и лучших методов, применяемых для написания читаемого кода.
1. Комментируйте & Документируйте
IDE (среды интегрированной разработки) за последние несколько лет прошли долгий путь. Это сделало комментирование кода более полезным, чем когда-либо. Следование определенным стандартам в комментариях позволяет IDE и другим инструментам в дальнейшем использовать их в разных случаях.
Рассмотрим пример:
Комментарии, добавленные в определение функции, могут просматриваться даже из других файлов каждый раз, когда функция используется.
Вот другой пример, когда я вызываю функцию из сторонней библиотеки:
Конкретно в этих примерах тип используемого комментария (или документации) основан на PHPDoc, а IDE — Aptana.
2. Согласованные отступы
Я полагаю, вы уже знаете, что в коде нужно делать отступы. Однако, эта хорошая идея имеет смысл только если ваш стиль отступа последователен.
Есть несколько способов введения отступов в код .
Способ 1:
1 2 3 4 5 6 7 8 9 |
function foo() { if ($maybe) { do_it_now(); again(); } else { abort_mission(); } finalize(); } |
Способ 2:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
function foo() { if ($maybe) { do_it_now(); again(); } else { abort_mission(); } finalize(); } |
Способ 3:
1 2 3 4 5 6 7 8 9 10 |
function foo() { if ($maybe) { do_it_now(); again(); } else { abort_mission(); } finalize(); } |
Я обычно пользовался способом № 2, но недавно переключился на способ № 1. Но это дело вкуса. Не существует «самого лучшего» способа, которому все должны следовать. Собственно, самый лучший способ – быть последовательным. Если вы – участник команды или вносите в проект код, нужно следовать тому способу, который используется в проекте.
Способы введения отступов не всегда можно полностью отличить один от другого. Иногда в них смешиваются различные правила. Например, в стандартах кодирования PEAR открывающая скобка «{» ставится в ту же строку, что и структуры управления, а они ставятся в следующую строку после определения функции.
Способ PEAR:
1 2 3 4 5 6 7 8 9 10 |
function foo() { // ставится в следующую строку if ($maybe) { // ставится в ту же строку do_it_now(); again(); } else { abort_mission(); } finalize(); } |
Также обратите внимание, что для введения отступов используется четыре пробела вместо табуляций.
Вот статья из Wikipedia с образцами разных способов введения отступов.
3. Избегайте очевидных комментариев
Комментирование кода – это прекрасно; однако, с ним можно перестараться или сделать его просто избыточным. Рассмотрим пример:
1 2 3 4 5 6 7 8 9 |
// получить код страны $country_code = get_country_code($_SERVER['REMOTE_ADDR']); // если код страны США if ($country_code == 'US') { // отобразить вставку формы для штата echo form_input_state(); } |
Когда текст и так очевиден, повторять его в комментариях совершенно непродуктивно.
Если действительно нужен комментарий к этому коду, его можно просто свести к одной строке:
1 2 3 4 5 |
// отобразить выбор штата для пользователей из США $country_code = get_country_code($_SERVER['REMOTE_ADDR']); if ($country_code == 'US') { echo form_input_state(); } |
4. Группировка кода
Чаще всего различные задачи требуют нескольких строк кода. Рекомендуется хранить эти задачи в рамках отдельных блоков кода с несколькими пробелами между ними.
Вот простейший пример:
1 2 3 4 5 6 7 8 9 10 11 |
// получить список форумов $forums = array(); $r = mysql_query("SELECT id, name, description FROM forums"); while ($d = mysql_fetch_assoc($r)) { $forums []= $d; } // загрузить шаблоны load_template('header'); load_template('forum_list',$forums); load_template('footer'); |
Можно зрительно отделить их при помощи добавления строки комментария в начале каждого блока кода.
5. Схема последовательного наименования
Сам PHP иногда виновен в том, что не следует схемам последовательного наименования:
strpos() vs. str_split()
imagetypes() vs. image_type_to_extension()
Прежде всего, в именах должны быть разграничены слова. Два самых популярных варианта:
camelCase: Первая буква каждого слова начинается с большой буквы, за исключением первого слова.
underscores: Подчеркивания между словами, как здесь: mysql_real_escape_string().
При существовании различных вариантов возникает та же ситуация, что и при введении отступов, о чем я ранее упоминал. Если в проекте следуют определенному правилу, вы тоже следуете ему. Кроме того, некоторые языковые платформы имеют тенденцию использовать определенную схему наименования. Например, в Java большинство кодов будут использовать имена в camelCase, а в PHP – имена с подчеркиваниями.
Эти соглашения также могут быть смешанными. Некоторые предпочитают использовать для процессуальных функций и названий классов подчеркивания, а для названий методов — camelCase:
1 2 3 4 5 6 7 8 9 10 11 |
class Foo_Bar { public function someDummyMethod() { } } function procedural_function_name() { } |
Повторяю, не существует очевидного «самого лучшего» способа, кроме последовательного.
6.Принцип DRY
DRY расшифровывается как Don’t Repeat Yourself (Не повторяйтесь). Также известен как DIE: Duplication is Evil (Повторение — зло).
Этот принцип гласит:
«Каждая крупица знания должно иметь единое, однозначное, авторитетное представление в системе.»
Предназначение большинства приложений (или компьютеров в целом) – в автоматизации повторяющихся заданий. Этот принцип должен соблюдаться во всем коде, даже в веб-приложениях. Один и тот же кусок кода не должен повторяться снова и снова.
Например, большинство веб-приложений состоят из многих страниц. Весьма вероятно, что эти страницы будут содержать общие элементы. Самые подходящие кандидаты для этого — верхние и нижние колонтитулы. Их копирование и вставка в каждую страницу – не самая лучшая идея. Здесь Jeffrey Way объясняет, как создавать шаблоны в CodeIgniter.
1 2 3 4 5 |
$this->load->view('includes/header'); $this->load->view($main_content); $this->load->view('includes/footer'); |
7. Избегайте глубоких вложений условных операторов
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
function do_stuff() { // ... if (is_writable($folder)) { if ($fp = fopen($file_path,'w')) { if ($stuff = get_some_stuff()) { if (fwrite($fp,$stuff)) { // ... } else { return false; } } else { return false; } } else { return false; } } else { return false; } } |
Чтобы сделать пример более ясным, нужно внести изменения, чтобы уменьшить уровень вложенности:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
function do_stuff() { // ... if (!is_writable($folder)) { return false; } if (!$fp = fopen($file_path,'w')) { return false; } if (!$stuff = get_some_stuff()) { return false; } if (fwrite($fp,$stuff)) { // ... } else { return false; } } |
8. Ограничивайте длину строк
Нашему глазу удобнее читать высокие и узкие колонки текста. Вот почему газетные статьи выглядят таким образом:
Очень полезно избегать написания очень длинных строк кода.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
// bad $my_email->set_from('test@email.com')->add_to('programming@gmail.com')->set_subject('Methods Chained')->set_body('Some long message')->send(); // good $my_email ->set_from('test@email.com') ->add_to('programming@gmail.com') ->set_subject('Methods Chained') ->set_body('Some long message') ->send(); // bad $query = "SELECT id, username, first_name, last_name, status FROM users LEFT JOIN user_posts USING(users.id, user_posts.user_id) WHERE post_id = '123'"; // good $query = "SELECT id, username, first_name, last_name, status FROM users LEFT JOIN user_posts USING(users.id, user_posts.user_id) WHERE post_id = '123'"; |
Если вы следуете совету «избегать глубоких вложений условных операторов», то это так же будет способствовать тому, чтобы длина строк кода оставалась в разумных размерах.
Также, если кто-то будет читать код из окна терминала, например пользователи vi, рекомендуется ограничить длину строки примерно 80 символами.
9. Организация файлов и папок
Технически вы можете записать код всего приложения в один файл. Но для чтения и поддержки это станет кошмаром.
Во время моих первых проектов по программированию я узнал об идее создания «включенных файлов». Однако я все еще был очень далек от организованности. Я создавал папку «inc» с двумя файлами внутри: db.php и functions.php. С ростом приложений файл функций становился огромным и сложно поддерживаемым.
Одним из лучших подходов к решению этой проблемы является использование framework’ов, либо их имитация с помощью структуры папок. Вот как выглядит CodeIgniter:
10. Последовательные имена промежуточных переменных
Обычно названия переменных должны быть информативными и содержать одно или более слов. Но это не обязательно относится к промежуточным переменным. Их имена могут быть настолько короткими, что могут состоять всего из одного знака.
Рекомендуется использовать одни и те же названия для тех промежуточных переменных, которые играют одинаковую роль. Вот примеры того, как я обычно использую их в коде:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
// $i for loop counters for ($i = 0; $i < 100; $i++) { // $j for the nested loop counters for ($j = 0; $j < 100; $j++) { } } // $ret for return variables function foo() { $ret['bar'] = get_bar(); $ret['stuff'] = get_stuff(); return $ret; } // $k and $v in foreach foreach ($some_array as $k => $v) { } // $q, $r and $d for mysql $q = "SELECT * FROM table"; $r = mysql_query($q); while ($d = mysql_fetch_assocr($r)) { } // $fp for file pointers $fp = fopen('file.txt','w'); |
11. Пишите зарезервированные слова SQL прописными буквами
Взаимодействие с базами данных – важнейшая часть большинства веб-приложений. Если вы пишете встроенные в программу запросы SQL, рекомендую поддерживать их читаемыми.
Даже если зарезервированные слова SQL и названия функций нечувствительны к регистру, их обычно пишут с прописными буквы, чтобы отличить от названий таблиц и столбцов.
1 2 3 4 5 6 7 8 9 10 11 |
SELECT id, username FROM user; UPDATE user SET last_login = NOW() WHERE id = '123' SELECT id, username FROM user u LEFT JOIN user_address ua ON(u.id = ua.user_id) WHERE ua.state = 'NY' GROUP BY u.id ORDER BY u.username LIMIT 0,20 |
12. Отделяйте код и данные
Вот другой принцип, который применяется почти ко всем языкам программирования в любой среде. В случае веб-разработки термин «данные» обычно предполагает выходные данные HTML.
Когда много лет назад впервые вышел PHP, он в основном рассматривался как движок шаблонов. Иметь большие HTML-файлы с несколькими строками кода внутри них было обычным делом. Однако за многие годы все изменилось и вебсайты стали гораздо более динамичными и функциональными. Сейчас код – огромная часть веб-приложения, и смешивание его с HTML — не очень хорошая практика.
Вы можете либо сами придерживаться этого правила в ваших приложениях, либо пользоваться при разработке дополнительными инструментами (движки шаблонов, frameworks или CMS) и просто соблюдать принятые в них соглашения.
Популярные фрэймворки PHP:
Популярные движки шаблонов:
Популярные системы управления контентом
13. Альтернативный синтаксис внутри шаблонов
Вы можете решить не использовать затейливый движок шаблонов, а выбрать простой встроенный PHP в файлах шаблонов. Это не обязательно нарушает принцип разделения кода и данных пока встроенный код напрямую связан с выходными данными и читаем. В этом случае вы можете использовать альтернативный синтаксис PHP для структур управления.
Вот пример:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
<div class="user_controls"> <?php if ($user = Current_User::user()): ?> Hello, <em><?php echo $user->username; ?></em> <br/> <?php echo anchor('logout', 'Logout'); ?> <?php else: ?> <?php echo anchor('login','Login'); ?> | <?php echo anchor('signup', 'Register'); ?> <?php endif; ?> </div> <h1>My Message Board</h1> <?php foreach($categories as $category): ?> <div class="category"> <h2><?php echo $category->title; ?></h2> <?php foreach($category->Forums as $forum): ?> <div class="forum"> <h3> <?php echo anchor('forums/'.$forum->id, $forum->title) ?> (<?php echo $forum->Threads->count(); ?> threads) </h3> <div class="description"> <?php echo $forum->description; ?> </div> </div> <?php endforeach; ?> </div> <?php endforeach; ?> |
Это позволяет избежать большого количества фигурных скобок. Кроме того, код выглядит и ощущается близко к тому, как структурируется и вводятся отступы в HTML.
14. Объектно-ориентированное vs. процедурное
Объектно-ориентированное программирование может помочь вам создать хорошо структурированный код. Но это не значит, что нужно полностью отказаться от процедурного программирования. Фактически, если смешать оба метода, то может получиться очень неплохо.
Объекты должны использоваться для представления данных, обычно находящихся в базе данных.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
class User { public $username; public $first_name; public $last_name; public $email; public function __construct() { // ... } public function create() { // ... } public function save() { // ... } public function delete() { // ... } } |
Процедурные функции могут быть использованы для специфических задач, которые выполняются независимо друг от друга.
1 2 3 4 5 6 7 |
function capitalize($string) { $ret = strtoupper($string[0]); $ret .= strtolower(substr($string,1)); return $ret; } |
15. Изучайте открытый исходный код
Проекты с открытым программным обеспечением (Open Source) почти всегда строятся на сотрудничестве многих разработчиков. Такие проекты должны поддерживать хороший уровень читаемости кода для того, чтобы команда могла работать как можно эффективнее. Поэтому очень полезно иногда просматривать исходный код таких проектов, наблюдая за тем, что делают их разработчики.
16. Разложение кода на элементы
Разложение на элементы означает внесение в код изменений без изменения его функциональности. Можно это назвать «чисткой» ради улучшения читаемости и качества.
Сюда не входит исправление ошибок или добавление функциональности. Можно разложить код, написанный вчера, пока он еще свеж в памяти, так, что он становится более читаемым и многократно используемым, чем если вы на него посмотрите через пару месяцев. Поэтому наш девиз звучит следующим образом: «разлагайте сразу, разлагайте часто».
Можно пользоваться любым из «лучших способов» повышения читаемости кода в процессе разложения на элементы.
Надеюсь, вам понравилась эта статья! Я что-нибудь упустил из виду? Напишите мне в комментариях.
Автор: Burak Guzel
Перевод и редакция: Рог Виктор и Андрей Бернацкий. Команда webformyself.
Источник: //net.tutsplus.com
P.S. Хотите опубликовать интересный тематический материал и заработать? Если ответ «Да», то жмите сюда.
Комментарии (1)