Статьи

15 лучших рекомендаций по написанию суперчитаемого кода

Дважды в месяц мы возвращаемся к любимым постам наших читателей на протяжении всей истории Nettuts +.

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


За последние несколько лет IDE (интегрированная среда разработки) прошла долгий путь. Это сделало комментирование вашего кода более полезным, чем когда-либо. Следование определенным стандартам в ваших комментариях позволяет IDE и другим инструментам использовать их по-разному.

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

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

Вот еще один пример, где я вызываю функцию из сторонней библиотеки:

В этих конкретных примерах используемый тип комментариев (или документация) основан на PHPDoc , а IDE — Aptana .


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

Существует несколько способов отступа кода.

1
2
3
4
5
6
7
8
9
function foo() {
    if ($maybe) {
        do_it_now();
        again();
    } else {
        abort_mission();
    }
    finalize();
}
01
02
03
04
05
06
07
08
09
10
11
12
13
function foo()
{
    if ($maybe)
    {
        do_it_now();
        again();
    }
    else
    {
        abort_mission();
    }
    finalize();
}
01
02
03
04
05
06
07
08
09
10
function foo()
{ if ($maybe)
    { do_it_now();
        again();
    }
    else
    { abort_mission();
    }
    finalize();
}

Я имел обыкновение кодировать в стиле # 2, но недавно переключился на # 1. Но это только вопрос предпочтений. Не существует «лучшего» стиля, которому должны следовать все. На самом деле, лучший стиль, это последовательный стиль. Если вы являетесь частью команды или вносите код в проект, вы должны следовать существующему стилю, который используется в этом проекте.

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

Груша Стиль:

01
02
03
04
05
06
07
08
09
10
function foo()
{ // placed on the next line
    if ($maybe) { // placed on the same line
        do_it_now();
        again();
    } else {
        abort_mission();
    }
    finalize();
}

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

Вот статья в Википедии с образцами разных стилей отступов.


Комментировать ваш код — это фантастика; однако, это может быть преувеличено или просто быть избыточным. Возьмите этот пример:

1
2
3
4
5
6
7
8
9
// get the country code
$country_code = get_country_code($_SERVER[‘REMOTE_ADDR’]);
 
// if country code is US
if ($country_code == ‘US’) {
 
    // display the form input for state
    echo form_input_state();
}

Когда текст настолько очевиден, повторять его в комментариях действительно непродуктивно.

Если вы должны прокомментировать этот код, вы можете просто объединить его в одну строку:

1
2
3
4
5
// display state selection for US users
$country_code = get_country_code($_SERVER[‘REMOTE_ADDR’]);
if ($country_code == ‘US’) {
    echo form_input_state();
}

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

Вот упрощенный пример:

01
02
03
04
05
06
07
08
09
10
11
// get list of forums
$forums = array();
$r = mysql_query(«SELECT id, name, description FROM forums»);
while ($d = mysql_fetch_assoc($r)) {
    $forums []= $d;
}
 
// load the templates
load_template(‘header’);
load_template(‘forum_list’,$forums);
load_template(‘footer’);

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


Сам PHP иногда виновен в несоблюдении последовательных схем именования:

  • strpos () против str_split ()
  • imagetypes () против image_type_to_extension ()

Прежде всего, имена должны иметь границы слов. Есть два популярных варианта:

  • camelCase: первая буква каждого слова пишется с большой буквы, кроме первого слова.
  • подчеркивание: подчеркивание между словами, например: mysql_real_escape_string ().

Наличие разных опций создает ситуацию, похожую на стили отступов, как я упоминал ранее. Если существующий проект следует определенному соглашению, вы должны пойти с этим. Кроме того, некоторые языковые платформы имеют тенденцию использовать определенную схему именования. Например, в Java большая часть кода использует имена camelCase, а в PHP — подчеркивания.

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

01
02
03
04
05
06
07
08
09
10
11
class Foo_Bar {
 
    public function someDummyMethod() {
 
    }
 
}
 
function procedural_function_name() {
 
}

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


СУХОЙ означает «Не повторяй себя». Также известный как DIE: Дублирование это зло.

Принцип гласит:

«Каждая часть знаний должна иметь одно, однозначное, авторитетное представление в системе».

Целью большинства приложений (или компьютеров в целом) является автоматизация повторяющихся задач. Этот принцип должен соблюдаться во всем коде, даже в веб-приложениях. Один и тот же кусок кода не должен повторяться снова и снова.

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

1
2
3
4
5
$this->load->view(‘includes/header’);
 
$this->load->view($main_content);
 
$this->load->view(‘includes/footer’);

Слишком много уровней вложенности может затруднить чтение и отслеживание кода.

01
02
03
04
05
06
07
08
09
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;
    }
}

Для удобства чтения обычно можно внести изменения в ваш код, чтобы снизить уровень вложенности:

01
02
03
04
05
06
07
08
09
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;
    }
}

Нашим глазам удобнее читать высокие и узкие столбцы текста. Именно поэтому газетные статьи выглядят так:

Рекомендуется избегать написания горизонтально длинных строк кода.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
// bad
$my_email->set_from(‘[email protected]’)->add_to(‘[email protected]’)->set_subject(‘Methods Chained’)->set_body(‘Some long message’)->send();
 
// good
$my_email
    ->set_from(‘[email protected]’)
    ->add_to(‘[email protected]’)
    ->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’»;

Кроме того, если кто-то намеревается прочитать код из окна терминала, например, пользователи Vim , рекомендуется ограничить длину строки примерно 80 символами.


Технически, вы можете написать весь код приложения в одном файле. Но это оказалось бы кошмаром, чтобы читать и поддерживать.

Во время моих первых программных проектов я знал об идее создания «включаемых файлов». Тем не менее, я еще не был даже отдаленно организован. Я создал папку «inc» с двумя файлами в ней: db.php и functions.php . По мере роста приложений файл функций также становился огромным и не поддерживаемым.

Один из лучших подходов — использовать фреймворк или имитировать структуру их папок. Вот как выглядит CodeIgniter:


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

Хорошей практикой является использование согласованных имен для ваших временных переменных, которые играют такую ​​же роль. Вот несколько примеров, которые я обычно использую в своем коде:

01
02
03
04
05
06
07
08
09
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’);

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

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

01
02
03
04
05
06
07
08
09
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

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

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

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

Популярные фреймворки PHP:

Популярные шаблоны двигателей:

Популярные системы управления контентом


Вы можете не использовать причудливый движок шаблонов, а вместо этого использовать простой встроенный PHP в своих файлах шаблонов. Это не обязательно нарушает «Разделение кода и данных», если встроенный код напрямую связан с выводом и доступен для чтения. В этом случае вам следует рассмотреть возможность использования альтернативного синтаксиса для структур управления .

Вот пример:

01
02
03
04
05
06
07
08
09
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;
        <?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;
 
        <?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 структурирован и имеет отступ.


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

Объекты должны использоваться для представления данных, обычно находящихся в базе данных.

01
02
03
04
05
06
07
08
09
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;
 
}

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


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

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

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

Надеюсь, вам понравилась эта статья! Любой, что я пропустил? Дайте мне знать через комментарии. И если вы хотите улучшить свое кодирование, на Envato Market есть множество скриптов и приложений, которые помогут вам. Посмотрите, что самое популярное на этой неделе .