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

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

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

За появление у системы новых свойств, отсутствующих по отдельности у её элементов, отвечает одна из закономерностей взаимодействия части и целого - эмерджентность. Эффект пересекается с диалектическим законом "перехода количества в качество", а в части влияния на систему и ухудшения каких-то её характеристик можно также вспомнить диалектическое противоречие и техническое противоречие в ТРИЗ.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Чрезвычайно любим в IT "синдром утёнка" (baby duck syndrome), при котором первый изучаемый язык, технология, концепция будет считаться самым лучшим и удобным, а все последующие - плохие. В этом случае выбор неподходящего стека под задачу запросто может иметь как технические проблемы, так и множество проблем со сложностью. Языки программирования, как и все инструменты, по большей части специализированы и создаются под конкретные задачи. Любая попытка натянуть на этот инструмент задачу другого инструмента будет заканчиваться неприятностями.

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

Очень распространён bike-shed effect, он же закон тривиальности Паркинсона, он же "закон велосипедного сарая": время, потраченное на обсуждение пункта, обратно пропорционально рассматриваемой сумме. Особенно он коварен в принятии решений на основе комментариев, чатов и т.п. форматов общения, предполагающих упрощённый ответ. Всестороннее рассмотрение и взвешивание преимуществ с недостатками очень быстро раздувает объём текста, что трудоёмко и сложно. Но любое упрощение создаёт шанс упустить (и упускает) детали, ибо понятия важное-неважное, сложное-простое тоже в общем-то субъективны.

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

Также нужно отдельно вспомнить ошибку конъюнкции или же проблему Линды, когда вероятность совместных событий оценивается выше, чем вероятность их по отдельности. Его коварство просто не имеет границ в условиях многогранного IT:

  • Программа написана на Java.
  • Программа написана на Java и имеет проблемы с производительностью.

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

Очень интересен здесь эффект Даннинга - Крюгера. Проблема в том, что многие (а если так разобраться - любые) задачи в общем-то комплексные, пересекаются с другими науками и знаниями. Даже эта статья потребовала усилий по перелопачиванию психологической литературы. Но если бы я психологию проигнорировал, считал гуманитарную науку недостойной и несерьёзной, то этот эффект сработал бы максимально сильно. Конечно, я подразумеваю именно более-менее научную психологию, а не популярную. Соответственно, любое отсутствие опыта или знаний сильно влияет на принимаемые решения, что создаёт противоречивые мнения: если написать на любом ресурсе статью вида X - плохое, а равно как Y - хорошее, то мнение в комментариях всегда разделится, на что сильно будет влиять опыт и квалификация, как и данный эффект.

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

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

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

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

Очень тонкой ловушкой может быть конформизм, что пересекается с социальной психологией. Так, например, стереотипно в IT сложное иногда считается авторитетным, а простое - это удел тех, кто не может освоить сложное. Соответственно, выбор переусложнённого решения может быть связано с нежеланием упрощения из-за потенциального влияния на авторитет, отношение со стороны коллег, ревьюеров и т.п. Стереотипы никто не отменял и некоторые языки программированию способны вешать на разработчика определённое клеймо: "если разработчик пишет на языке X, то он такой-то, работает там-то и знает это, а вот в этом не разбирается совсем". Здесь усматриваются пересечения с ролевой теорией в социологии, как и эффектом ореола.

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

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

Здесь можно вспомнить закон Конвея: организации проектируют системы, которые копируют структуру коммуникаций в этой организации. А эти коммуникации могут быть очень разными. В итоге иногда выходит схожий эффект с Free-to-play играми: на начальных уровнях задачи успешно выполняются, но более сложные уровни требуют дополнительных трат ресурсов - денег или времени, а отказаться уже нельзя из-за потерянных ресурсов, как и недоделанного результата. Здесь по аналогии в некоторых инструментах можно учуять след маркетинга, в котором эти пользовательские действия просчитываются изначально. Было бы странным, если бы тамошние высококвалифицированные специалисты по маркетингу этого бы не делали, скорее наоборот, из-за высокой их квалификации этот маркетинг обнаружить крайне сложно.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Путаница может быть из-за незначительных различий в символах, регистре, именах и синтаксических конструкциях: y и Y, l и L и т.п. в зависимости от особенностей шрифта, дистанции от монитора и зрения. Особенно это актуально для командной строки, склонной к сокращениям для упрощения использования.

Много очень коротких имён переменных встречается в научном коде (например, математическом) или циклах (i, j, k и т.д), что легко перепутать. Обратная связь от системы может нарушаться из-за слишком маленьких элементов в интерфейсе, мелкого шрифта или слабого контраста текста, когда элемент банально не замечается.

Здесь будет срабатывать адаптация, вырабатывая привыкание. С другой стороны, если привыкание к чему-то требует времени, то при перерыве и отвыкании снова потребуется время. Это время можно учитывать, планируя обслуживание приложения, фикс багов и переделки.

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

Например, a + b кем-то будет восприниматься как математическая операция, кем-то как конкатенация строк, а кем-то как перегрузка оператора у какого-то неизвестного типа. Метод getTextWriter может восприниматься как геттер, хотя на самом деле быть фабричным методом. С другой стороны, такое имя сильно упрощает его нахождение: при наличии в языке геттеров и сеттеров с соглашениями в именовании, часто первым делом в исследовании нового апи пробуются get... и set... с изучением подсказок со стороны IDE. Тоже самое с заменой конструкторов на статические фабричные методы, найти и пользоваться которыми намного сложнее чем вызвать new и посмотреть подсказки перегрузок. Залезть в исходный код для изучения конструкторов также может быть намного проще.

Число может восприниматься как знаковое, а быть беззнаковым, как и наоборот. Типы могут инициализироваться различными значениями по умолчанию, как и не инициализироваться вообще, поэтому, например, double x не обязано должно быть 0. Результат деления двух целых чисел может ожидаться дробным, когда как он будет целым, что распространено повсеместно. Статические данные могут восприниматься глобальными, как и быть в TLS. В языках с различными подходами к разделению ресурсов между потоками вызовы могут восприниматься не в том потоке, в котором они происходят, как и различные операции некорректно восприниматься атомарными или безопасными. И т.д. и т.п.

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

Восприятие подчиняется различным сложным механизмам и законам, дотошно изучаемых в той же гештальтпсихологии. В части кода можно вспомнить, например, принципы близости и подобия, когда расположенные рядом элементы воспринимаются вместе. Здесь, наверное, можно притянуть за уши распространённое повышение short до int в числовых операциях: short a = 1, b = 2; c = a + b. Поскольку тут везде short, то и результат склонен восприниматься как short, хотя это, конечно же, не так.

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

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

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

С другой стороны, для новичка, который только знакомится с инструментом, понятие фабрики может восприниматься как запутывающее, а какой-нибудь Creator воспринимался бы намного лучше. Фабрики распространены в предметно-ориентированном программировании (Domain driven design) по заветам Эванса, встречаются во многих порождающих паттернах, но это совершенно не значит, что их восприятие разными людьми будет одинаковым.

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

У взрослого человека объём внимания около 5-7 (4-6) элементов, зависимый от множества факторов. Эти ограничения требуют разделять поступающую информацию на части, как и удалять лишний шум, вызывающий непроизвольное внимание. Однако как и в аналогии с context switch для процессора, здесь появляется проблемы переключения внимания, которая осложняется при его высокой концентрации, что может приводить к ошибкам и неудобствам. Так, система должна заботится о сохранении и восстановлении состояний: давать информацию куда было обращено внимание раньше, где была приостановка, в каком состоянии сейчас она находится и что делать дальше. Соблюсти эти инварианты не так-то и просто.

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

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

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

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

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

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

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

Особо много проблем создаёт память - накопление, сохранение и воспроизведение знаний. Кратковременная память подчиняется закону Миллера (кошелёк Миллера) - 7 ± 2 элементов.

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

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

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

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

Например, очень удобны синтаксические метаданные: UDA (User Defined Attributes), аннотации и т.п., что сильно сокращает код, экономит время и упрощает использование, что критично важно для более сложных систем, в которых иначе сделать трудно.

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

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

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

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

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

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

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

Вероятно, ограничения мышления, как и суммирование проблем восприятия, воображения, представления и т.п. связаны с нелюбовью юзабилити к режимам. Любой режим - источник ошибок и путаницы. Можно вспомнить классический пример кнопок Lock\Unlock, когда Lock говорит о разблокированном состоянии, а Unlock о блокированном, но многие интуитивно воспринимают это наоборот. Отсутствие чёткого различия и одинаковые команды в разных режимах могут доставить массу проблем.

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

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

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

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

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

И т.д. и т.п.

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

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

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

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

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

Групповой фаворитизм, упоминаемый ранее эффект ореола, эффект "мы и они" могут влиять на согласие (или несогласие) с другими экспертами, влияя на восприятие их слов и аргументов.

Групповая поляризация и сдвиг к риску могут приводить к более рискованным решениям.

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

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

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

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

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

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

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

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

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

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

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