Как обойтись без лишних сложностей при написании кода и обучении программированию

17 комментариев
Как обойтись без лишних сложностей при написании кода и обучении программированию

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

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

Управление сложностью – это суть компьютерного программирования (Брайан Керниган).

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

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

  • Изучить код
  • Отметить стилистические и структурные соглашения, используемые в базе кода
  • Познакомиться с инфраструктурой проекта и инструментарием

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

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

Почему возникает сложность?

Любой дурак может написать код, который понятен компьютеру. Хорошие программисты пишут код, который понятен человеку (Мартин Фаулер)

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

Излишние вложения

Пренебрегая управляющими конструкциями, можно наворотить чрезмерно глубокие последовательности вложенных операторов. Притом, что они исключительно усложняют синтаксический анализ кода. Кроме того, такой код очень неудобно расширять.
Объясню эту проблему на примере, а в качестве предисловия немного обрисую контекст. Допустим, у нас есть приложение на Java с методом generateResponseObject(), который возвращает экземпляр класса, расширяющего (наследующего) ResponseObject. Существует шесть типов объектов, которые может возвращать этот метод.

public ResponseObject generateResponseObject(String route) {
  ResponseObject responseObject;
  if (route.equals("time")) {
    responseObject = new TimeResponse();
  } else if (route.equals("echo")) {
    responseObject = new EchoResponse();
  } else if (route.equals("redirect")) {
    responseObject = new RedirectResponse();
  } else if (route.equals("file")) {
    responseObject = new FileResponse();
  } else {
    responseObject = new FormResponse();
  }
  return responseObject;
}

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

Вот один из потенциальных способов избежать этой сложности.

public ResponseObject generateResponseObject(HashMap<String, ResponseObject> routes) {
  ResponseObject responseObject;
  String route = httpRequestContent.get("route");
  responseObject = routes.get(route);
  return responseObject;
}

Мы разобрали запрос и сохранили его в хеш-таблице. Теперь для доступа к маршруту мы просто получаем значение для ключа "route". Зная этот маршрут, мы сможем просмотреть конкретный подкласс ResponseObject из хеш-таблицы, где ключами будут, например, "time", "echo" и "redirect", а значениями – соответствующие объекты, полученные при отклике. Случайно возникшая сложность устранена, код более понятен и удобен для расширения.

Сильное связывание

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

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

При включении в код множества файлов, каждый из которых, в свою очередь, содержит множество файлов, обычно возникают баги (многие из которых сложно отслеживать). Любой, кому придется позже работать с этим кодом, будет путаться, особенно если местоположение конкретных функций явно не указано. В статье Modules called, they want their integrity back Джош Чик описывает некоторые подводные камни, связанные с непродуманным включением модулей, реализующих ненужный или неожиданный функционал.

Неверное форматирование

Существуют антипаттерны форматирования, связанные с расстановкой отступов, пробелов, именованиями и комментированием, из-за которых восприятие кода излишне усложняется. Особенно следует отметить важность правильного именования, поскольку грамотно составленные названия методов значительно облегчают жизнь разработчику. Аналогично, важно учитывать количество и имена параметров. Хотя, подобные ошибки усложняют код не так сильно, как излишне глубокие вложения, их не стоит сбрасывать со счетов. Рассмотрим следующий пример:

(defn resume-game []
  (let [file-name (get-file)
          game-type     (:game-type file-name)]
    (if (= 1 game-type)
      (display "We've loaded your game. It's the computer's turn.")
    (display "We've loaded your game. It's the human's turn."))))

Это простая функция, но чтобы ее понять, требуется приложить некоторые усилия. Дело в несогласованном использовании отступов, пробелов и имен. Давайте подробнее рассмотрим ошибки, допущенные в это функции. Отступы в специальной форме let отличаются на каждой из трех строк. Такая же проблема с отступами наблюдается и в специальной форме if. Поскольку в Clojure подразумевается else, важно правильно выравнивать код, чтобы обеспечить его удобочитаемость. Кроме того, отметим ненужный пробел после связки game-type. Наконец, имена тоже очень странные. Может показаться, что file-name соответствует содержимому, а не имени файла. Значение game-type выражается в целых числах; соответственно, речь идет не о типе игры, а о числе, ассоциируемом с типом игры.   

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

Параметры сложности кода

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

Сложность организации циклов в программе

Наиболее распространенный параметр для анализа сложности кода называется «Cyclomatic Metric» (уровень сложности циклов в программе). Он измеряет структурную сложность, определяемую в результате анализа логики управляющих конструкций (в сущности – количество путей в программе). Этот параметр был предложен Томасом Маккейдом, рекомендовавшим разработчикам измерять сложность кода, и если ее коэффициент превышает 10 – разбивать код на более мелкие модули. Данный параметр, конечно же, не гарантирует точной характеристики сложности софтверной системы, но он хорошо помогает при оценке покрытия кода тестами.

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

Параметры сложности Голстеда

В 1977 году Морис Голстед предложил учитывать ряд оценочных атрибутов, в частности, длину (length), словарь (vocabulary), объем (volume), трудоемкость (difficulty) и количество усилий (effort), затраченных на написание кода. В основном, эти параметры основаны на оценке операторов (изменений данных) и операндов (изменяемых данных) в коде.

Длина кода зависит от количества операторов и операндов. Сложность, обусловленная словарными проблемами, определяется степенью уникальности операторов и операндов (где небольшое количество часто повторяемых единиц свидетельствует о сравнительно низкой сложности). Первые два параметра в комбинации образуют третий – объем. Объем позволяет судить о сложности кода в зависимости от размера базы кода. Трудоемкость связана с написанием и поддержкой кода, причем она прямо пропорциональна количеству уникальных операторов и операндов. Наконец, количество усилий связано с объемом и трудоемкостью кода. Все эти параметры определяются по исходному коду, выполнять код при этом не требуется. 

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

Принцип абсолютного приоритета

Мика Мартин в одноименной статье предложил «условие абсолютного приоритета» (Absolute Priority Premise) как средство оценивания кода для объективного суждения о нем. Поскольку мы привыкли расценивать код в зависимости от его статических и динамических качеств – а такие оценки по определению являются субъективными – Мика попытался исключить из этой системы критериев динамический аспект. В качестве отправной точки он взял «условие очередности преобразований» (Transformation Priority Premise). В презентации Мики меня особенно заинтересовал тезис о том, что разработка через тестирование (TDD) может давать далеко не идеальные алгоритмы в случаях, когда решение достигается окольным путем. Подобный «далеко не идеальный» путь возникает именно из-за упомянутой выше случайной сложности. Не всегда удается с уверенностью определить, на каком этапе зародилась такая сложность, и как от нее избавиться. Потенциальная польза условия абсолютного приоритета (APP) заключается в том, что он позволяет присваивать различным операциям балльные значения. При этом, учитываются сущности шести категорий: константы, связки, вызовы методов, условные операторы, циклы и операторы присваивания. Каждый из этих компонентов добавляет баллы к общей сумме. Так, константа оценивается в 1 балл, а цикл while – в 5 баллов. В сумме получаем общую «массу» кода, по которой мы можем судить об общей сложности кода. Теоретически, малая сумма должна свидетельствовать о том, что данное решение является сравнительно простым, прямолинейным и не содержит лишних ненужных наворотов.    

Где и как можно снижать случайную сложность?

Мы уже обсудили ряд способов устранения излишней сложности в коде. Однако, задолго до того, как приступить к написанию кода, приходится разобраться еще с одной проблемой. Согласно Дейкстре, кривая сложности, связанной с написанием ПО, получается тем круче, чем больше «радикально новых» концепций задействуется в коде. Распространено мнение, что для усвоения новой информации требуется выстраивать связи между нею и уже имеющимися знаниями. Но Дейкстра считал метафоры обычными «костылями». При обучении все мы испытываем определенные трудности (все мы, независимо от нашего опыта), и суть таких проблем во многом объясняется тем, что мы пытаемся впихнуть квадратную чурку в круглое отверстие. Вероятно, случайные сложности возникают в базе кода по вине тех разработчиков, которым пришлось учиться у плохих преподавателей и наставников. Эта наука регулярно их подводит и, как следствие, разработчики становятся более подвержены таким ошибкам. Вероятно, пути устранения ненужной сложности следует искать не на уровне написания кода, а на уровне обучения программированию.

Более двадцати лет назад Дейкстра написал статью «О суровости настоящего преподавания информатики», в которой сделал важное замечание, не потерявшее актуальности и сегодня:

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

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

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

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

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

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

Горячие события

Testing Stage 2020
26 марта — 28 марта

Testing Stage 2020

Киев
JSNation 2020 Amsterdam
3 июня — 5 июня

JSNation 2020 Amsterdam

Amsterdam

Читайте также

Разработчики Долины засомневались в плюсах работы в стартапах
Разработчики Долины засомневались в плюсах работы в стартапах

Разработчики Долины засомневались в плюсах работы в стартапах

Обитатели Кремниевой долины как ни во что другое верят, что будущее — за стартапами, пишет Quartz. Но всё больше разработчиков перестаёт смотреть на работу в них через розовые очки.
15 комментариев
Коронавирус переводит сотрудников на «удалёнку». ИТ, статистика, паника
Коронавирус переводит сотрудников на «удалёнку». ИТ, статистика, паника

Коронавирус переводит сотрудников на «удалёнку». ИТ, статистика, паника

С разгулом китайского коронавируса возможность работать удалённо становится не приятным бонусом для сотрудников или способом сэкономить для нанимателей, а вынужденной необходимостью, пишет Bloomberg.
Dice 2020 Salary Report: самые оплачиваемые технические специальности, навыки и города США
Dice 2020 Salary Report: самые оплачиваемые технические специальности, навыки и города США

Dice 2020 Salary Report: самые оплачиваемые технические специальности, навыки и города США

Dice: самые востребованные у работодателей программистские навыки связаны с данными
Dice: самые востребованные у работодателей программистские навыки связаны с данными

Dice: самые востребованные у работодателей программистские навыки связаны с данными

3 комментария

Обсуждение

Anonymous
Anonymous Team Leader в Softeq Development
2

На мой взгляд неудачный способ решения для первого примера на Java введя метод

public ResponseObject generateResponseObject(HashMap routes)

Там же новые экземпляру не создаются. Как вариант можно держать в этом Map классы и создавать экземпляр через default конструктор с помощью reflection. Но это не сильно упростит понимание.

3

Самое интересное в этом примере, что последнее условие:

} else {
responseObject = new FormResponse();
}

означает "по умолчанию (если ничего не подошло) отдавай мне FormResponse". Не уверен, что авторское решение с HashMap этот случай учитывает...

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

2

Ну и каша в голове у автора.
Первый пример - не пример избежания сложности в коде, а пример переехода от одного патерна к другому. В примере явная сложность кода. Чтобы уйти от нее и облегчить расширяемость кода (и сопровождение тоже) достаточно развернуть if -ы (не использовать else[if] конструкцию) и только.
А тема, действительно, интересная.
Я считаю, что мало в обучении программистов уделяется внимания вопросам стандртизации написания кода. Языки и технологии изучаем, а культуре написания кода, особо, и не учат.

1

А в чём будет упрощение при замене "else if" на "if" (я правильно вас понял)?
Вот уже есть несколько вариантов решить "проблему" в примере 1:
1. Создать мап с классами и использовать reflection, как предложили в предыдущем комменте.
2. Убрать else
3. Использовать switch/case
4. Оставить как есть
5. Подозреваю, что ещё несколько других вариантов.
И какому "стандартному" варианту предлагаете учить? :)

-2

Отличный пример... я вот такому всё ни как не научусь...
предложить целых 5 (!) вариантов решения проблемы... из которых один уже повторение предложенного, один неэффективный и ещё два ни о чём...
Никита, в вас "золотой" менеджер пропадает :)

-1

Спасибо, я рад, что вы оценили меня по достоинству.
На самом деле вы себя недооцениваете, у вас тоже получилось написать комментарий, в котором больше текста, чем смысла. Жаль только, что мы скатились в бесмысленный офтопик.

-2

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

Anonymous
Anonymous ведущий инженер-программист в SCAND
1

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

0

Я бы не стал решать за большинство, тем более ни чем не аргументируя своё мнение.

Anonymous
Anonymous ведущий инженер-программист в SCAND
-1

Ну хорошо, могу и разжевать мысль для вас персонально.
Надо определиться, для кого эта статья и кого будем учить.
Вариант 1: Бесконечно мудрое и прекрасное создание - Сферического программиста в вакууме. Тут надо задуматься, а много ли таких есть, сколько из них прочитает статью и найдёт там что-то новое для себя.
Вариант 2: Новичков. Для них всё новое, и часто есть проблема - как вообще сделать то, что от них требуют. В этот момент новички вряд ли вспомнят много букаф, но есть шанс, что вспомнят какие-то простые и наглядные примеры.
И вообще, я считаю, что если берёмся учить людей делать что-то "без лишних сложностей", то логично было бы и делать это без лишних сложностей.

Anonymous
Anonymous Team Leader в Softeq Development
0

К разумному написанию кода надо подходить постепенно. Приучать с самого начала с помощью code review, naming conventions соглашениях по форматированию и т.д.
Был неоднозначный опыт в прошлом по выставлению требований по Cyclomatic complexity к уже существующему приличному объему кода. Включали специальный tool по проверке сложности и заставляли разработчиков переделывать. Причем в достаточно сжатые сроки.
Результат бы неоднозначный.
Требования были например длина метода не больше 200 строк. В спешке делали так. Вместо одного
public void myMethod() {
...
}

писали
public void myMethod() {
...
myMethod2(); //просто скопированный кусок кода из оригинального метода.
}

Ограничения по числу параметров в методе (требовали не больше 5) упирались в SUN Java код. Вызвать super было невозможно.

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

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

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

1

А еще люди должны понимать зачем все это делать. То есть надо "давить" аргументацией, а не тупо требовать.

0

Забавно, в комменте ниже я себе противоречу :) Будем считать это "уточнением".

-1

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

0

По поводу 40 часов.

Если у человека свое видение того, как надо работать и писать код, то ты его не переубедишь. И опыт тут не всегда оказывает влияние. Например, человек (образно) 10 лет клепал говносайты и все было ок, и вдруг столкнулся с другим характером проектов. Ты ему говоришь: "Друг, ты не прав", а он тебя не слушает (у него же 10 лет "опыта" и свое мнение).

А еще есть мнение (где-то выше уже озвучили): "Хотелки клиента - главное, качество кода - потом когда-нибудь наверное может быть...". Ты ему говоришь: "Парень, а может давай сразу хотелки качественно пилить? А не потом переделывать". Но, как вы помните, там же 10 лет опыта. Говносайты обычно пишутся с первого раза, так почему тут не прокатит?

Но вы правы: 40 часов учебы * 10 лет опыта = упертый баран (то есть я хотел сказать "специалист") с 10-ю годами типа-опыта и раздутым самомнением. В таком случае бэйджик "Супер сеньёр тим-лид" может и помог бы продавить правильное решение... Но если бэйджики-морковки дают за "года опыта", то круг замыкается.

Так что да, лучше бы люди учились.

-2

всё верно, как видите, даже ваш пример это подтверждает.
"свое видение, как надо работать и писать код" = "недостаток знаний"
"10 лет клепал говносайты и все было ок, но вдруг столкнулся с другим характером проектов" = "недостаток знаний"
"а он тебя не слушает...упертый баран...свое мнение" = "низкая дисциплина"
"качество кода - потом когда-нибудь наверное может быть..." = "низкая дисциплина"
Диагноз: "недостаток знаний", "низкая дисциплина".
Лечение: от недостатка знаний учить. По поводу низкой дисциплины. Глядя на качество работы некоторых "ИТ-специалистов", даже порой "опытных", как в вашем примере, иногда складывается мнение, что помимо знаний им очень не хватает ...люлей. Ну ладно... это уже личное...
Кстати "низкая дисциплина" отчасти лечится и устранением "недостатка знаний". Если человек, как вы пишите, "10 лет клепал говносайты в своём болотце" и "раздул самомнение", что он уже гуру и последняя инстанция в вопросах, как надо делать, поэтому никого не слушает, работает как хочет, пишет код только как ему заблагорассудится, то зачастую бывает, это "раздутое самомнение" очень быстро и сдувается. Когда, например, “из болотца своего, из своей зоны комфорта, вылазит” (сам или обстоятельства заставят) и для себя потом "открывает" целые новые направления и области. И знакомится со специалистами с гораздо меньшим "самомнением", но квалификацией просто на порядки выше.
Поэтому ничего нового, всё подобное только от 1) нежелания учиться 2) нежелания думать. А сон разума, как известно, рождает чудовищ. "Раздутое самомнение" ещё не самое худшее из них...

Сергей Скоков
Сергей Скоков Senior Software Engineer в EPAM
-1

Весьма забавно читать статью об упрощении с примерами усложнения. Чем автору if-else-if конструкция не понраву. Сразу виден весь контракт. Что нужно передать в метод, что метод вернет. А в результате получилось размазывание логики по методам. Поди и собери в голове как это работает... Похоже автор больше теоретик, чем кодо-писатель.