company_banner

10 идей, о которых стоит знать всем программистам

Автор оригинала: Peter Christian Fraedrich
  • Перевод
Я пишу на Python и на Go, а в последние годы занимаюсь крупномасштабными приложениями. Речь идёт о том, что каждый день мне и моей команде приходится поддерживать системы, ответственные за обеспечение работы примерно двух миллионов пользователей. Это — непростая задача. Здесь я хочу поделиться несколькими ценными идеями, которые встретились мне за годы работы.



1. Не надо решать вопросы безопасности в последнюю очередь


Системы безопасности приложений крайне не рекомендуется реализовывать в последнюю очередь, или сводить всё к такой мысли: «Сделаем безопасность как-нибудь потом». Для того чтобы создать безопасное приложение, вопросы безопасности должны быть на повестке дня с самого первого дня работы над проектом. Если оставлять разработку системы безопасности на последний дедлайн, то это, на самом деле, лишь увеличит сроки разработки, так как придётся возвращаться к уже написанному коду и рефакторить его для приведения в соответствие с нуждами безопасности. Или всё может сложиться ещё хуже: из-за нехватки времени на «затыкание» всех «дыр» всё закончится тем, что в продакшн попадёт код, в котором будут уязвимости. А это, как несложно убедиться, проанализировав опыт разных компаний, вроде Yahoo, может закончиться очень плохо.

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


Пожалуй, об этом можно и не говорить, но я всё же скажу о том, что все приложения отличаются друг от друга. Нет некоего свода непреложных правил, применимого ко всем проектам (включая и это правило). Когда вы начинаете работу над новым проектом, выбор технологий и платформ, на которых будет основано приложение, должен определяться лишь особенностями самого приложения и его архитектуры. Если принимать решение о том, использовать ли gRPC или Kubernetes, до того, как будет задан вопрос: «А что нужно приложению?», — это означает — ставить препятствия на собственном пути ещё до начала работы над кодом. Именно так разные компании и попадают в абсурдные ситуации. Например, в ситуации вроде той, когда Canonical предлагает Kubernetes для IoT-устройств. Позволю себе процитировать тут фразу Джеффа Голдблюма из фильма «Парк Юрского периода»: «Да, но ваши учёные столь увлеклись, добиваясь этого, что даже не задумались: «Стоит ли?»».

3. Микросервисы нужны далеко не всем


Микросервисы крайне привлекательны. Мне это понятно. Идея, в соответствии с которой можно независимо масштабировать разные части приложения, восхитительна. Она способна оправдать дополнительные объёмы работ, которые необходимы некоему проекту. Но давайте будем честны с собой: вам, возможно, микросервисы не нужны. Предположим, идею применения микросервисов пытаются поддержать следующими соображениями: «Хочу отделить код возможности X от кода возможности Y», «Хочется, чтобы плохой код из одних частей приложения не проникал бы в другие его части», «Нужно минимизировать последствия возможного взлома приложения». Но всё это нельзя назвать причинами, руководствуясь которыми необходимо переходить на микросервисы. Это, соответственно, симптомы применения плохих подходов к разработке (не лезь в чужие дела, меняй только то, что необходимо), низких стандартов код-ревью (некачественному коду нечего делать в ветке master) и недостатков в сфере безопасности.

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

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

4. Стандартизированное окружение разработки — это хорошо


Если вы руководите командой разработчиков, то одно из самых полезных решений, которое вы можете принять, это решение о применении единого окружения разработки. Причём, я тут не имею в виду необходимость строить нечто вроде контейнеризованного виртуального окружения. Вы вполне можете сделать и это, если хотите, но даже применение простого правила, вроде использования одной и той же версии языка, может творить чудеса. Например, серьёзно потрепать себе нервы можно, попытавшись отладить ошибку в Go 1.12, в то время как ваш коллега, обратившийся к вам за помощью, пишет код на Go 1.11. Координация обновлений может быть достаточно сложной задачей, но если подойти к организации этого процесса правильно, всё будет делаться легко и приятно.

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


В отличие от того, что можно прочитать на некоторых популярных сайтах, создать подсистему, отвечающую за настройки приложения, немного сложнее, чем «положить всё в переменные окружения». Я полагаю, что нужно предусматривать не менее четырёх способов конфигурирования приложений: значения по умолчанию, задаваемые в коде, локальный конфигурационный файл, флаги командной строки, переменные окружения, удалённый источник настроек (вроде HashiCorp Consul). Удалённый источник настроек я назвал бы необязательным. Но другие четыре механизма просто необходимы. Если в процессе разработки, только для того, чтобы запустить приложение, нужно записать в переменные окружения 27 значений, то это, если мягко выразиться, не так уж и удобно. Кроме того, может быть вам нужен более высокий уровень автоматизации и Makefile? Если предусмотреть настройку приложения через локальный файл, вроде application.yaml, это может значительно облегчить описание конфигурации, применяемой, по умолчанию, при разработке. Кроме того, если в коде есть значения, используемые по умолчанию, это означает, что задавать эти значения нужно только тогда, когда нужно что-то, отличающееся от стандартных настроек. Флаги командной строки весьма полезны в ситуациях, когда приложения запускают с помощью разных средств автоматизации, вроде systemd. Это облегчает анализ конфигурации при трассировке процессов. Конечно, переменные окружения крайне полезны при запуске приложений в контейнерах, но есть некоторые задачи, для решения которых они не подходят. Например, переменные окружения не стоит использовать для хранения паролей.

В переменные окружения категорически не рекомендуется записывать что-то секретное: пароли, токены аутентификации, сертификаты, в общем — всё, что вы не хотели бы сделать достоянием широкой общественности. Проблема тут в том, что значения переменных окружения может прочитать практически любой процесс, работающий на компьютере. Для хранения секретных данных нужно использовать какое-то специализированное решение. Лично я для этих целей выбрал HashiCorp Vault, но я не призываю пользоваться именно этим сервисом. Выбирайте то, что лучше всего подходит для вашего проекта.

6. Зависимости стоит использовать тогда, когда они нужны


Полагаю, все помнят о left-pad-апокалипсисе? Как 11-строчный пакет, который убрали из репозитория, поломал, в сущности, весь интернет? Этот инцидент приводит к одной простой мысли: «Не стоит, без реальной необходимости, подключать к проекту дополнительные зависимости». Зависимости стоит использовать только тогда, когда в них есть обоснованная необходимость. Какие зависимости по-настоящему нужны в проектах? Например — это может быть пакет, представляющий собой SDK для платформы, с которой вы работаете (SDK AWS, например). Это может быть некая хорошая абстракция над неудобными стандартными библиотеками (именно поэтому программисты пользуются Python-библиотекой Requests вместо urllib). Это может быть какой-то широко используемый фреймворк — вроде HTTP-сервера Echo, написанного на Go, или WSGI-сервера Flask, написанного на Python. Некие библиотеки, реализующие удобные методы, которых нет в языке, вроде библиотеки Lodash для JavaScript-проектов, тоже относятся к «обоснованным» зависимостям.

Внешние зависимости должны упрощать разработку и не должны заставлять программиста самого писать какой-то вспомогательный код. Именно в упрощении разработки и заключается сильная сторона менеджеров пакетов. Но, как и в случае с left-pad, пользуясь менеджером пакетов легко попасть в ловушку, когда к любой задаче применяется такой подход: «Для этого есть библиотека, значит я ей воспользуюсь». С каждой импортированной в проект зависимостью растёт риск того, что проект может стать нестабильным, небезопасным, или попросту необслуживаемым.

Этот риск увеличивает и каждый пакет, используемый новой зависимостью. Такие пакеты называются транзитивными зависимостями. Если вы импортируете в проект всего одну зависимость, которая, в свою очередь, импортирует пять пакетов, то ваш проект тоже становится зависимым от этих пакетов, а значит — все проблемы этих пакетов становятся и его проблемами. И по моему мнению, и по мнению других программистов, прямые зависимости проектов не должны иметь транзитивных зависимостей. Но это не всегда возможно. Хотя, если речь идёт об очень больших пакетах, то они должны иметь как можно меньше зависимостей. А если пользователям таких пакетов нужен какой-то дополнительный функционал, у них должна быть возможность самостоятельно подключать такой функционал.

Я, принимая решения об импорте зависимостей в свои проекты, следую простому правилу: если я могу что-то написать за 10-15 минут, то я так и делаю. В противном случае я, если есть такая возможность, импортирую в проект некую библиотеку. Это правило может уберечь вас от импорта в приложение всякого хлама, но оно, в то же время, достаточно гибкое, и не принуждает программиста к тому, чтобы он каждый раз, когда ему нужно организовать работу API, писал бы собственный HTTP-сервер.

7. Не нужно писать абстракции до тех пор, пока в этом не возникнет реальная необходимость


Современному программисту очень легко попасть в ловушку абстрагирования всего и вся. Мысли о том, что нечто может понадобиться использовать повторно, способны завести разработчика в тёмные и страшные дебри ООП. И мне удалось понять причину этого. Принципы DRY (Don’t Repeat Yourself, не повторяйтесь) глубоко укоренились в нашем сознании. И не без причины. Но есть граница, пересекая которую, мы тратим на абстрагирование сущностей слишком много времени, а на написание кода — слишком мало. Поэтому вот вам совет: «Просто пишите код!». Если вы столкнулись с необходимостью реализовать функцию, похожую на что-то такое, что вы уже написали, тогда вы можете вернуться к старому коду и заняться созданием абстракции. Но, опять же, тут надо знать меру. Я применяю здесь такое правило: если речь идёт о маленькой функции в три строчки, то, вероятно, её можно просто написать, пусть и повторившись. Но если в функции содержится всего три строки кода, то, вероятно, я задамся вопросом о том, что, возможно, этот код и не стоит оформлять в виде функции.

8. Иногда свой проект стоит «сжигать» и «возрождать из пепла»


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

Представьте, что ваш проект — это огромный лес. Каждая строка кода — могучая сосна. По мере того, как лес стареет, он зарастает подлеском, его засыпает сосновыми иголками, шишками, сухими ветками… Это — ваши проблемы, ваш технический долг. Всё это имеет свойство накапливаться. Этот процесс, сам по себе, никогда не останавливается. Остановить его могут лишь некие радикальные изменения. В лесу изменения приносят пожары. Огонь очищает лес от всего ненужного. Сильные деревья остаются, а всякая мелочь сгорает. Хотя пожар может показаться катастрофой, которая уничтожит лес, тут есть один секрет: лес ждёт пожара. Ждёт терпеливо, годами. Лес надеется на то, что огонь очистит его и станет причиной изменений. Дело в том, что пока пламя бушует под кронами сосен, в их шишках созревают семена, из которых вырастут новые мощные деревья. В то время как огонь сжигает лесную подстилку, он освобождает место для нежных молодых деревьев, которые займут своё место рядом с выжившими ветеранами леса, опалёнными огнём. Именно такими должны быть и приложения: их надёжные, хорошо написанные части переживут «пожар», а место того, что будет «сожжено», займут новые идеи и новый код. И проект, как Феникс, возродится из пепла.

9. Ваша компания — это не Google


Нет, если вы работаете в Google, то я ничего против не имею. Но если это так, то скажите, а зачем вы вообще это читаете? Собственно говоря, моя идея заключается в том, что ваша компания — это, скорее всего, не Google, Microsoft, Amazon, Twitter или Facebook. Вам не нужно думать о том, как управлять 150000 контейнеров на 10000 «железных» серверов, расположенных в 17 дата-центрах, разбросанных по всему миру. Проблемы, которые перед вами встают, обычно не затрагивают каждого жителя Земли. Кстати, а зачем я об этом всём говорю? А затем, что размеры вашей организации должны определять масштабность используемых вами платформ. Например, вы пользуетесь несколькими сотнями контейнеров. Вам и правда не обойтись без Kubernetes? И обязательно ли вам запускать эти контейнеры на собственных серверах? Может, вы просто, поступая так, хотите казаться солиднее? Для решения подобных мелко- и среднемасштабных задач отлично подходит что-то наподобие HashiCorp Nomad. Подобные платформы легко настраивать. Их не нужно поддерживать, а если они и нуждаются в поддержке, то особых усилий на это не требуется. Они хорошо документированы. На них очень легко переносить приложения, так как они рассчитаны на работу с контейнерами, с системными процессами и с JVM-приложениями. А если вам никак не обойтись без Kubernetes, то почему бы не пользоваться этой платформой, прибегнув к чему-то вроде Rancher? Это позволит снять с себя задачи по настройке всяческих мелких деталей. Нагрузка, связанная с использованием сложных систем, вроде Kubernetes, слишком велика для некоей отдельной команды разработчиков, скажем, для команды стартапа. Эти системы, кстати, разработаны крупными компаниями, вроде Google, и предназначены для таких же компаний. Я бы даже сказал так: стартапам стоит любой ценой избегать Kubernetes — за исключением тех случаев, когда их продукт неразрывно связан с данной платформой. Пожалуй, тут есть одно исключение: облачные предложения от Google, Amazon и Microsoft. Ничего плохого я о них сказать не могу, так как эти компании снимают с пользователей нагрузку по управлению сложными системами. Но я очень вас прошу: никогда не пользуйтесь Kubernetes на IoT-устройствах.

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


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

Что вы добавили бы к тем идеям, о которых мы только что говорили?



RUVDS.com
RUVDS – хостинг VDS/VPS серверов

Комментарии 39

    +8

    Пассаж про лес достоин оваций!

      +2

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

        +2
        image
          +3

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


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

            +1
            Это неизбежно.
            Требования постоянно меняются, код в ответ обрастает костылями, т.к. разработан под старые требования.
            В какой-то момент код превращается в сложноподдерживаемый кусок ужаса.

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

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

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

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

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

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


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


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

                0
                А еще забывают, что новый код надо протестировать. и это занимает немало времени!
            +2
            На самом деле когда бизнес идея отточена до мелочей, переписать код с улученной эволючионной архитектурой не так уж и сложно. За 30+ лет в IT я это делал как минимум 10 раз, и каждый раз успешно. Одна мной переписанная система прорабоала под нагрузкой 18 лед пока ее не списали, другой уже 14 лет, еще одна уже 10 лет в проде.
              0
              ну для маленьких проектов — это вполне себе вариант.
              если происходит хрень с компиляцией или отображением + изначально было выбрано не самое лучшее решение — бывает.
              у меня есть софт, который я продаю. маленький софт для маленьких компаний. клиентов от 200 до 300. месячная подписка.
              изначально софт писался для себя на питоне (анализ данных + ручки).
              первая версия софта — питон без гуи (тупо терминал). однако продавалось
              вторая версия — гуи на питоне.
              третья — гуи на электроне — с подгрузкой питоновского скомпилированного файлика.
              последняя версия пока — большинство вещей переделано на js для визуальности. питоновский файлик еще жив, служит теперь больше для защиты кода, которого жалко, что сопрут. примерно 80% кода с изначального проекта так или иначе переписано.
              стоит ли все стирать и массово переписывать — ну врядли.
              стоит ли со временем переписывать, оптимизировать — ну да.
              совет, конечно, слишком радикальный.
              0
              Это сравнение ужасно! Нет, лес не ждёт пожара, это не очищение для леса и его жителей, а катастрофа и смерть.
              0

              Да, да. И так каждый новый раз! А через полгода — что за дерьмо мы написали....


              Больше похоже на гуманитария мечтателя когда такое пишут…

                0
                Мб автор жёг только сосняки, а вот у нас огонь с радостью поднимается по елям, после чего шишки также отправляются к праотцам вместе с семенами. Как родственник человека, работающего в сфере, рекомендовал бы полиции присматривать, как этот Пётр проводит отпуск )
                –7

                Что такого сложного в кубернетесе? Не заметил никакого порога вхождения, он, если не вдаваться в мелкие детали, простой (в хорошем смысле, simple) и очень понятный (в смысле yml)

                  0

                  Я уверен, что многие вещи стоит сейчас делать на основе не голого kubernetes, а на основе knative, который работает в kubernetes.
                  Пользователь knative оперирует небольшим количеством сущностей, имеет большое количество "плюшек".


                  А "сложности" kubernetes решает уже тот, кто развернул knative. Впрочем, это ведь уже несложно, когда ты успешно развернул knative :)

                    +5
                    дада

                    +5
                    Пожалуй, последую последнему совету.
                      +1

                      Согласен, пожалуй самый ценный совет… Остальные не все даже рассматривать надо вне концепта "спорим с хайпом".

                      +1
                      Помимо опыта работы с высоконагруженными системами, У Питера ощущается солидный опыт разработки за спиной. Советы здравые и взвешенные.
                      Насчет сжигания леса, я бы добавил что частота переделки с нуля зависит от инновационности проекта.
                        –2

                        Глыбко, йобко, феерично

                          +1

                          Совет использовать Nomad или rancher вместо кубера если вам нужно запускать "сотню контейнеров" выглядит как минимум необычно.
                          Более того, использование контейнеров сразу при разработке, эмулируя окружение тем же compose сильно облегчает жизнь в дальнейшем.

                            +1

                            Rancher сейчас и есть одним из дистрибутивов kubernetes, свой самописный оркестратор они уже похоронили.

                            +4
                            Что-то я думал тут будет про рекурсию и подобное, даже с любопытством заглянул посмотреть. А тут какие-то измышления частного порядка, которые не то чтобы всем программистам знать не надо, а даже и один раз прочитать необязательно. Извините, но заголовок не соответствует.
                              0
                              скрытая реклама Hashicorp, встречается пару раз
                                +2

                                А ссылки на гитхаб — реклама MS?

                                0
                                10 идей, о которых стоит знать всем программистам

                                Ваша компания — это не Google

                                Занавес
                                  +3

                                  Боже, судя по комментам — мы обречены.
                                  Никто не собирается следовать советам — простым и правильным в большинстве случаев. Каждый суслик в поле агроном.
                                  И самое страшное — это происходит сплошь и рядом, не только в программировании. Уроки истории никому не интересны. Похоже третья мировая не избежна.

                                    0
                                    Эта идея заставляет менеджеров нервничать. Она портит настроение владельцам продукта. Она злит программистов. Но «возрождение из пепла» — это совершенно необходимо. Время от времени начинать всё сначала — это хорошо.


                                    Интересно, хоть одна комерческая компания так делала, после 2-20 человеко-лет разработки?
                                      0
                                      Да. Но почти всех постигла участь Netscape. Он умерли. За последние 25 лет есть очень мало успешных примеров переписывания продукта с нуля, а кладбище колоссально.
                                      0
                                      Как боженька смолвил.

                                      Другое дело что это просто список очевидных вещей. Но если вам вдруг так не кажется, и при этом вы считаете себя разработчиком (возможно крутым), добро пожаловать вон из профессии
                                        0
                                        > 6. Зависимости стоит использовать тогда, когда они нужны
                                        Пакетоманьяки. Ради какого-то дополнения строки слева или использования конкурентных фьючерсов/промисов готовы ставить 11-строчные библиотеки на каждый чих, вместо написания алгоритма просто у себя в отдельном файле. Если так хочется готовый код, то возьми и скопируй его себе без зависимости. Но городить милионные зависимости просто потому что «так правильно бэст практис чувак» — это есть безумие.

                                        > 7. Не нужно писать абстракции до тех пор, пока в этом не возникнет реальная необходимость
                                        Да за неиспользования DRY, GRASP, GoF и прочего иногда вас готовы сжечь уже прямо на собеседовании.
                                          0
                                          11. Земля круглая
                                            +1
                                            По поводу необходимости абстракций я лично пришел к таком правилу:
                                            если видишь два похожих класса или функции, и при этом они достаточно просты, то подумай о том почему они похожи,
                                            если их похожесть это просто случайность, то лучше оставить все как есть, и не создавать никаких доп. абстракций. Если же они похожи потому что это реально связанные вещи в предметной области, то лучше сделать абстракцию.
                                            Со сложными функциями конечно по другому, сложность всегда хочется где-то спрятать, забыть и никогда не доставать.
                                              0
                                              Рекомендации отличные!
                                              Многие могут сказать «мы всё это и так знали», но «суть не в том, что мы знаем, а в том, чем мы пользуемся».
                                              Спасибо за статью! :-)
                                                0
                                                Давно известные факты. К тому же это приходит ко всем без исключений(хотя исключения тоже есть).
                                                Нужно сделать что-то простое, но гениальное
                                                  0
                                                  8. — «сжигать» и «возрождать из пепла»

                                                  архитектурный ребут?

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

                                                  Самое читаемое