Advertisement
  1. Web Design
  2. HTML/CSS
  3. HTML

Лучшие 15+ практик написания читабельного кода

Scroll to top
Read Time: 11 min

() translation by (you can also view the original English article)

Два раза в месяц, мы пересматриваем статьи, которые нравятся больше всего нашим пользователям на сайте Nettuts+.

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


1 - Комментарии и документация

IDE (Integrated Development Environment, среда разработки) прошли долгий путь за последние пять лет. Тем самым комментирование кода, стало важным аспектом, как никогда раньше. Следование определённым стандартам комментариев, позволяет IDE и другим инструментам обрабатывать их различными методами.

Взгляните на пример:

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

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

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


2 - Последовательные отступы

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

Есть несколько способов добавить отступы в код.

Стиль 1:
1
2
function foo() {
3
  if ($maybe) {
4
		do_it_now();
5
		again();
6
	} else {
7
		abort_mission();
8
	}
9
	finalize();
10
}
Стиль 2:
1
2
function foo()
3
{
4
	if ($maybe)
5
	{
6
		do_it_now();
7
		again();
8
	}
9
	else
10
	{
11
		abort_mission();
12
	}
13
	finalize();
14
}
Стиль 3:
1
2
function foo()
3
{	if ($maybe)
4
	{	do_it_now();
5
		again();
6
	}
7
	else
8
	{	abort_mission();
9
	}
10
	finalize();
11
}

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

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

Стиль PEAR:

1
2
function foo()
3
{                     // placed on the next line

4
    if ($maybe) {     // placed on the same line

5
        do_it_now();
6
        again();
7
    } else {
8
        abort_mission();
9
    }
10
    finalize();
11
}

Также обратите внимание на четыре пробела вместо табов для индентации.

Вот статья на Wikipedia с примерами различных стилей отступов.


3 - Избегайте очевидных комментариев

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

1
2
// get the country code

3
$country_code = get_country_code($_SERVER['REMOTE_ADDR']);
4
5
// if country code is US

6
if ($country_code == 'US') {
7
8
	// display the form input for state

9
	echo form_input_state();
10
}

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

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

1
2
// display state selection for US users

3
$country_code = get_country_code($_SERVER['REMOTE_ADDR']);
4
if ($country_code == 'US') {
5
	echo form_input_state();
6
}

4 - Группировка кода

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

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

1
2
3
// get list of forums

4
$forums = array();
5
$r = mysql_query("SELECT id, name, description FROM forums");
6
while ($d = mysql_fetch_assoc($r)) {
7
	$forums []= $d;
8
}
9
10
// load the templates

11
load_template('header');
12
load_template('forum_list',$forums);
13
load_template('footer');

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


5 - Последовательное именование

PHP сам по себе иногда не следует последовательной договорённости об именах:

  • strpos() и str_split()
  • imagetypes() и image_type_to_extension()

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

  • Верблюжья нотация (camelCase): первая буква каждого слова - заглавная, за исключением первого слова.
  • Нижнее подчёркивание: нижнее подчеркивание между словами, к примеру: mysql_real_escape_string().

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

Данные правила можно совмещать. Некоторые разработчики предпочитают нижнее подчёркивание для функций и имён классов, но верблюжью нотацию для названий методов:

1
2
class Foo_Bar {
3
4
	public function someDummyMethod() {
5
6
	}
7
8
}
9
10
function procedural_function_name() {
11
12
}

Тем самым, как и прошлый раз у нас нет очевидного "лучшего" стиля. Просто оставайтесь последовательным.


6 - Принципы DRY

DRY - Don't Repeat Yourself (не повторяйтесь) Также известен как DIE: Duplication is Evil (повторение - зло).

Данные принципы означают:

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

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

К примеру, большинство веб-приложений состоят из множества страниц. Наверняка эти страницу будут содержать одинаковые элементы. Шапки и футеры обычно лучшие кандидаты на эту роль. Не самая лучшая идея копировать и вставлять шапку и футер на каждую страницу. Здесь Jeffrey Way объясняет как создать шаблоны в CodeIgniter.

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

7 - Избегайте глубокого вложения

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

1
2
function do_stuff() {
3
4
// ...

5
6
	if (is_writable($folder)) {
7
8
		if ($fp = fopen($file_path,'w')) {
9
10
			if ($stuff = get_some_stuff()) {
11
12
				if (fwrite($fp,$stuff)) {
13
14
					// ...

15
16
				} else {
17
					return false;
18
				}
19
			} else {
20
				return false;
21
			}
22
		} else {
23
			return false;
24
		}
25
	} else {
26
		return false;
27
	}
28
}

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

1
2
function do_stuff() {
3
4
// ...

5
6
	if (!is_writable($folder)) {
7
		return false;
8
	}
9
10
	if (!$fp = fopen($file_path,'w')) {
11
		return false;
12
	}
13
14
	if (!$stuff = get_some_stuff()) {
15
		return false;
16
	}
17
18
	if (fwrite($fp,$stuff)) {
19
		// ...

20
	} else {
21
		return false;
22
	}
23
}

8 - Ограничьте длину строки

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

Хорошая практика - не писать длинные горизонтальные строки текста.

1
2
3
// bad

4
$my_email->set_from('test@email.com')->add_to('programming@gmail.com')->set_subject('Methods Chained')->set_body('Some long message')->send();
5
6
// good

7
$my_email
8
	->set_from('test@email.com')
9
	->add_to('programming@gmail.com')
10
	->set_subject('Methods Chained')
11
	->set_body('Some long message')
12
	->send();
13
14
// bad

15
$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'";
16
17
// good

18
$query = "SELECT id, username, first_name, last_name, status

19
	FROM users

20
	LEFT JOIN user_posts USING(users.id, user_posts.user_id)

21
	WHERE post_id = '123'";

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


9 - Организация директорий и файлов

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

Во время работы над первым проектом связанным с программированием, я знал, что следует разделять код, создавать "include файлы". Однако, я совсем не был организован нужным образом. Я создал папку под названием "inc", с двумя файлами: db.php и functions.php. По мере роста функционала приложения, файл с функциями стал огромным и невероятно затруднительным в поддержке.

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


10 - Последовательные временные имена

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

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

1
2
3
// $i for loop counters

4
for ($i = 0; $i < 100; $i++) {
5
6
	// $j for the nested loop counters

7
	for ($j = 0; $j < 100; $j++) {
8
9
	}
10
}
11
12
// $ret for return variables

13
function foo() {
14
	$ret['bar'] = get_bar();
15
	$ret['stuff'] = get_stuff();
16
17
	return $ret;
18
}
19
20
// $k and $v in foreach

21
foreach ($some_array as $k => $v) {
22
23
}
24
25
// $q, $r and $d for mysql

26
$q = "SELECT * FROM table";
27
$r = mysql_query($q);
28
while ($d = mysql_fetch_assocr($r)) {
29
30
}
31
32
// $fp for file pointers

33
$fp = fopen('file.txt','w');

11 - Заглавная буква для специальных SQL слов

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

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

1
2
SELECT id, username FROM user;
3
4
UPDATE user SET last_login = NOW()
5
WHERE id = '123'
6
7
SELECT id, username FROM user u
8
LEFT JOIN user_address ua ON(u.id = ua.user_id)
9
WHERE ua.state = 'NY'
10
GROUP BY u.id
11
ORDER BY u.username
12
LIMIT 0,20

12 - Разделяйте код и данные

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

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

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

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

Популярные шаблонизаторы:

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


13 - Альтернативный синтаксис в шаблонах

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

Вот пример:

1
2
<div class="user_controls">
3
	<?php if ($user = Current_User::user()): ?>
4
		Hello, <em><?php echo $user->username; ?></em> <br/>
5
		<?php echo anchor('logout', 'Logout'); ?>
6
	<?php else: ?>
7
		<?php echo anchor('login','Login'); ?> |
8
		<?php echo anchor('signup', 'Register'); ?>
9
	<?php endif; ?>
10
</div>
11
12
<h1>My Message Board</h1>
13
14
<?php foreach($categories as $category): ?>
15
16
	<div class="category">
17
18
		<h2><?php echo $category->title; ?></h2>
19
20
		<?php foreach($category->Forums as $forum): ?>
21
22
			<div class="forum">
23
24
				<h3>
25
					<?php echo anchor('forums/'.$forum->id, $forum->title) ?>
26
					(<?php echo $forum->Threads->count(); ?> threads)
27
				</h3>
28
29
				<div class="description">
30
					<?php echo $forum->description; ?>
31
				</div>
32
33
			</div>
34
35
		<?php endforeach; ?>
36
37
	</div>
38
39
<?php endforeach; ?>

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


14 - Объектно-ориентированный против процедурного подхода

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

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

1
2
class User {
3
4
	public $username;
5
	public $first_name;
6
	public $last_name;
7
	public $email;
8
9
	public function __construct() {
10
		// ...

11
	}
12
13
	public function create() {
14
		// ...

15
	}
16
17
	public function save() {
18
		// ...

19
	}
20
21
	public function delete() {
22
		// ...

23
	}
24
25
}

Процедурные функции могут подойти для определённых задач, которые выполняются независимо.

1
2
function capitalize($string) {
3
4
	$ret = strtoupper($string[0]);
5
	$ret .= strtolower(substr($string,1));
6
	return $ret;
7
8
}

15 - Чтение кода с открытым доступом

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


16 - Рефакторинг кода

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

Сюда не входят исправления багов или добавления нового функционала. Вы можете рефакторить код, который был написан за день до этого, пока вы всё ещё прекрасно помните, за что он отвечает, делая его более читабельным и позволяя повторно использовать, даже после того, как вы не видели его пару месяцев. Как гласит лозунг: "refactor early, refactor often (рефакторь как можно раньше, рефакторь часто)".

Вы можете применять любую из этих "лучших практик" во время процесса рефакторинга.

Я надеюсь вам понравилась эта статья! Если я что-то пропустил. Сообщите мне об этом в комментариях.

Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Web Design tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.