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

С вашими новыми навыками вы решаете начать проект. Помимо приложения для дел. Что-то действительно здорово.

Все начинается хорошо. Вы знаете, как писать код, поэтому вы пишете код. И пиши еще. И более.

Но по мере того, как вы углубляетесь, все оказывается не так просто. Этот первый раздел кода нуждается в соединении с другой частью. Итак, вы вносите изменения. Но подождите, этому второму разделу также нужны некоторые соединения, так что вы их делаете. Обо всем этом становится все труднее думать, но ты стал программистом не потому, что был глуп. Вы можете понять это. Так что вы делаете. Вы настаиваете. Кодирование и кодирование. Все замедляется, потому что вам приходится все больше и больше думать о каждом изменении, которое вы делаете. Но вы делаете это, потому что вы умны и у вас есть настойчивость. Мама не сутулилась. Вы сделаете это.

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

Но что, если нам или кому-то еще нужно внести изменения через три месяца? Это будет очень тяжело. Мы забыли, почему написали то, что сделали, и будет трудно понять, что произойдет, когда мы внесем изменения. Это как тянуть один кусок спагетти на тарелке, не зная, какие другие нити будут двигаться, когда мы это сделаем.

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

Как мы пишем хороший код? Код, с которым мы будем рады работать через три месяца?

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

Шесть сестер

Есть шесть принципов, которые приведут нас к здоровому и хорошему коду. Я называю их Шесть Сестер. Это принципы, а не законы. Иногда они дерутся. Когда вы пытаетесь слушать одного, другой говорит вам что-то другое. Но в целом они сделают вашу жизнь (особенно вашу будущую жизнь) намного проще. Познакомьтесь с инкапсуляцией, связностью, связью, избыточностью, тестируемостью и читабельностью.

Инкапсуляция

Инкапсуляция означает, что мы пишем код, инкапсулированный небольшими частями. Когда мы помещаем что-то в эту часть кода, мы получаем ожидаемое. Это также означает, что наш код не изменяет то, чего мы не хотим или не ожидаем. Это похоже на черный ящик, в котором нет ничего неожиданного или сложно представить ссылки на другие места. Если мы положим кролика в нашу коробку с кодом и каждый раз получим утку, это будет хороший код. Нам все равно, как код дает нам утку. Мы не должны думать об этом. Мы можем просто подумать: «Мне нужно превратить этого кролика в утку. О да, у меня есть коробка, которая сделает это».

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

Из всех сестер Encapsulation — самая старшая, самая властная, и к ней следует прислушиваться больше всего. Она упрощает изменение нашего кода, потому что мы знаем, что наши изменения повлияют только на коробку. И она облегчает обдумывание нашего кода. Когда мы строим коробку, нам нужно думать только о том, как она работает — что она вбирает и что выплевывает. Когда мы закончим сборку коробки, нам не нужно думать о том, как она работает. Мы просто сажаем кроликов и достаем уток, когда нам нужно. Возможность думать о коробке только тогда, когда мы создаем ее, а затем переключаться на размышления только о том, что она делает, когда мы ее используем, а не о том, как она работает, делает наш код и более легким для размышлений, и более легким для изменения. .

Сплоченность

Чтобы создать связный код, мы спрашиваем себя, насколько связан каждый фрагмент кода в нашей коробке? Все ли части этого кода работают для одного и того же? Если мы построим коробку, в которую поместится кролик, а дадут нам утку и белку, это может быть здорово, если мы каждый раз хотим утку и белку (хотя я бы сказал, что тогда это даже не здорово). Но что произойдет, если мы захотим только утку или только белку? Поскольку кодовые кролики дешевы, лучше построить две коробки. В одном вы кладете кролика и получаете утку. Другой вы посадите кролика и получите белку. Это сплоченность. Этот кусок кода делает одну вещь — делает утку.

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

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

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

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

Связь

Итак, мы превратили наш код в маленькие коробки. Большой. Теперь нам нужно их соединить. Связывание — это то, как мы соединяем блоки кода друг с другом. Он определяет, как данные будут выходить из одного поля и входить в другое.

Если у нас нет связи, у нас есть набор ящиков, которые не являются системой. Части, которые действительно не связаны. Как автомобильный двигатель, который разваливается на части. Наша программная система нуждается в соединении, но не слишком.

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

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

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

Избыточность

Осознание избыточности означает, что мы стараемся не писать один и тот же код в нескольких местах. Если мы хотим изменить код позже, и он находится в нескольких местах, нам нужно внести несколько изменений. Размещая дублирующийся код в одном месте, мы можем изменить его в одном месте. Это меньше работы и легче думать — большую часть времени.

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

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

Тестируемость

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

Как отмечает Скотт Бейн в своей превосходной книге Emergent Design, если у вас возникли проблемы с написанием тестов, это может быть связано с тем, что ваш код не следует принципам связности, связанности и избыточности.

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

Возможность легко тестировать наш код — это проверка, которая помогает нам придерживаться хороших методов кодирования.

Читабельность

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

Удобочитаемость означает хорошие комментарии, которые объясняют, почему вы приняли такое решение. Задайте себе вопрос: «Если бы я впервые прочитал этот код, понял бы я его?» Если нет, то что нужно изменить, чтобы сделать его таким?

Заключение

О каждом принципе нужно узнать больше. Тем не менее, шесть сестер — это то, что делает хороший код. Инкапсуляция дает нам общий способ сделать наш код легким для изменения и легким для размышлений. Сплоченность, связанность и избыточность идут рука об руку с инкапсуляцией и помогают нам сохранять наши блоки кода инкапсулированными, как они должны быть. Тестируемость поддерживает связность, связанность и избыточность, направляя их в правильном направлении. А читабельность подталкивает всю нашу кодовую базу к двум целям — легко изменить и легко обдумать.

В этом суть хорошего кода. Послушайте «Шесть сестер», и ваше будущее «я» скажет вам спасибо.