Читаем Рефакторинг. Зачем? полностью

Ещё одна рекомендация, связанная с именованием функций и переменных — не использовать сокращений. Исключения составляют очевидные, часто используемые сокращения (например, Rect — достаточно распространённое сокращение слова Rectangle). Надо понимать, что сокращение, очевидное для вас сейчас, может быть совершенно не очевидно для вашего коллеги или для вас через месяц.

<p><strong>Стандартные имена функций и переменных</strong></p>

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

Какие можно привести примеры:

— практически все называют переменные цикла буквами i, j, k, для циклов первой, второй и третьей вложенности соответственно;

— какие–то временные, короткоживущие переменные часто снабжают префиксом «temp» или «tmp», например, tempFileName для файла, который вскоре удалится;

— логические переменные становятся куда нагляднее с префиксами типа is, has, can, например, isButtonVisible, canAddPoint, hasPoint;

— в случае коптрования данных из одной переменной в другую, лучше использовать префиксы source и dest, а не суффиксы 1 и 2, «copy(array1, array2)» выглядит менее понятно, чем «copy(sourceArray, destArray)».

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

<p><strong>Преобразование одной большой функции в две маленькие</strong></p>

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

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

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

type

TRect = record

Left: Integer;

Right: Integer;

Top: Integer;

Bottom: Integer;

end;

function RectsLength(Rects: array of TRect): Integer;

var

I: Integer;

Width, Height: Integer;

begin

Result:= 0;

for I:= 0 to Length(Rects) — 1 do

begin

 Width:= Rects[I].Right — Rects[I].Left;

Height:= Rects[I].Bottom — Rects[I].Top;

 Result:= Result + 2 * Width + 2 * Height;

end;

end;

Выше приведён простой пример, который рассчитывает сумму периметров прямоугольников в массиве. Пока он не выглядит сильно сложным, но, предположим, что задача немного изменилась и нам сказали не учитывать прямоугольники площадью меньше некоего числа MinLength.

function RectsLength(Rects: array of TRect; MinLength: Integer): Integer;

var

I: Integer;

Width, Height, Len: Integer;

begin

Result:= 0;

for I:= 0 to Length(Rects) — 1 do

begin

 Width:= Rects[I].Right — Rects[I].Left;

Height:= Rects[I].Bottom — Rects[I].Top;

Len:= 2 * Width + 2 * Height;

if Len >= MinLength then

 Result:= Result + Len;

end;

end;

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

function RectLength(Rect: TRect): Integer;

var

Width, Height: Integer;

begin

 Width:= Rect. Right — Rect. Left;

Перейти на страницу:

Похожие книги

97 этюдов для архитекторов программных систем
97 этюдов для архитекторов программных систем

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

Билл де Ора , Майкл Хайгард , Нил Форд

Программирование, программы, базы данных / Базы данных / Программирование / Книги по IT
Programming with POSIX® Threads
Programming with POSIX® Threads

With this practical book, you will attain a solid understanding of threads and will discover how to put this powerful mode of programming to work in real-world applications. The primary advantage of threaded programming is that it enables your applications to accomplish more than one task at the same time by using the number-crunching power of multiprocessor parallelism and by automatically exploiting I/O concurrency in your code, even on a single processor machine. The result: applications that are faster, more responsive to users, and often easier to maintain. Threaded programming is particularly well suited to network programming where it helps alleviate the bottleneck of slow network I/O. This book offers an in-depth description of the IEEE operating system interface standard, POSIX (Portable Operating System Interface) threads, commonly called Pthreads. Written for experienced C programmers, but assuming no previous knowledge of threads, the book explains basic concepts such as asynchronous programming, the lifecycle of a thread, and synchronization. You then move to more advanced topics such as attributes objects, thread-specific data, and realtime scheduling. An entire chapter is devoted to "real code," with a look at barriers, read/write locks, the work queue manager, and how to utilize existing libraries. In addition, the book tackles one of the thorniest problems faced by thread programmers-debugging-with valuable suggestions on how to avoid code errors and performance problems from the outset. Numerous annotated examples are used to illustrate real-world concepts. A Pthreads mini-reference and a look at future standardization are also included.

David Butenhof

Программирование, программы, базы данных