Когда Мюррея Гелл-Манна спросили, как Ричарду Фейнману удалось решить так много сложных проблем, Гелл-Манн ответил, что у Фейнмана есть алгоритм:
- Запишите проблему.
- Думай очень усердно.
- Запишите решение.
Гелл-Манн пытался объяснить, что Фейнман был другим человеком, решающим проблемы, и не было никакого понимания, которое можно было бы получить при изучении его методов. Я чувствую то же самое в отношении управления сложностью в средних / крупных программных проектах. Хорошие люди просто хороши в этом и каким-то образом умудряются наслоить и сложить различные абстракции, чтобы сделать все это управляемым без какого-либо постороннего вмешательства.
Так является ли алгоритм Фейнмана единственным способом управления случайной сложностью, или существуют ли реальные методы, которые инженеры-программисты могут последовательно применять для устранения случайной сложности?
источник
Ответы:
По моему опыту, самая большая причина случайной сложности - программисты, придерживающиеся первого варианта, просто потому, что это работает. Это то, чему мы можем научиться на наших уроках английского по композиции. Они строят вовремя, чтобы пройти несколько проектов в своих заданиях, включая обратную связь с преподавателем. Уроки программирования, по какой-то причине, нет.
Существуют книги, полные конкретных и объективных способов распознавания, формулирования и исправления неоптимального кода: « Чистый код» , « Эффективная работа с устаревшим кодом» и многие другие. Многие программисты знакомы с этими методами, но не всегда находят время для их применения. Они вполне способны уменьшить случайную сложность, они просто не привыкли пробовать .
Отчасти проблема в том, что мы не часто видим промежуточную сложность кода других людей, если только он не прошел экспертную оценку на ранней стадии. Чистый код выглядит так, как будто его было легко написать, хотя на самом деле он обычно состоит из нескольких черновиков. Сначала вы пишете лучший способ, который приходит вам в голову, замечаете ненужные сложности, которые он вводит, а затем «ищите лучший ход» и реорганизуете, чтобы устранить эти сложности. Затем вы продолжаете «искать лучший ход», пока не найдете его.
Тем не менее, вы не отправляете код на проверку до тех пор, пока не пройдете весь этот отток, поэтому внешне это выглядит так, как будто это был процесс, подобный Фейнману. У вас есть склонность думать, что вы не можете делать все это одним куском, поэтому вы не пытаетесь, но правда в том, что автор этого прекрасного простого кода, который вы только что прочитали, обычно не может написать все это одним куском. или так, или если они могут, это только потому, что у них был опыт написания подобного кода много раз прежде, и теперь они могут видеть шаблон без промежуточных этапов. В любом случае, вы не можете избежать сквозняков.
источник
«Навыку архитектуры программного обеспечения нельзя научить» - распространенная ошибка.
Легко понять, почему многие люди в это верят (те, кто в этом хороши, хотят верить, что они мистически особенные, и те, кто не хочет верить, что это не их вина, что они не таковы). тем не менее неправильно; навык просто более практичен, чем другие программные навыки (например, понимание циклов, работа с указателями и т. д.)
Я твердо верю, что создание больших систем восприимчиво к повторяющейся практике и обучению на собственном опыте так же, как превращение в великого музыканта или оратора: минимальное количество талантов является предварительным условием, но это не удручающе огромный минимум из охват большинства практикующих.
Работа со сложностью - это навык, который вы приобретаете, в основном, пытаясь и терпя неудачу несколько раз. Просто многие общие руководящие принципы, которые сообщество обнаружило для программирования в целом (использовать слои, бороться с дублированием, где бы он ни поднимал голову, неукоснительно придерживаться 0/1 / бесконечность ...), не столь очевидно правильны и необходимы для начинающий, пока они на самом деле не запрограммировать что-то большое. Пока вас не укусила дублирование, которое вызвало проблемы только спустя месяцы, вы просто не можете «понять» важность таких принципов.
источник
Прагматичное мышление Энди Ханта решает эту проблему. Это относится к модели Дрейфуса, согласно которой существует 5 ступеней владения различными навыками. Новички (этап 1) нуждаются в точных инструкциях, чтобы уметь что-то делать правильно. Эксперты (этап 5), напротив, могут применить общие закономерности к данной проблеме. Ссылаясь на книгу,
Это общее правило наблюдения (и, как следствие, избежания) различных проблем может быть применено именно к проблеме случайной сложности. Наличие данного набора правил недостаточно, чтобы избежать этой проблемы. Всегда будет ситуация, которая не подпадает под эти правила. Нам нужно набраться опыта, чтобы предвидеть проблемы или находить решения. Опыт - это то, чему нельзя научить, его можно получить только путем постоянных попыток, неудач или успехов и обучения на ошибках.
Этот вопрос от Workplace является актуальным, и ИМХО было бы интересно прочитать в этом контексте.
источник
Вы не объясняете это, но «случайная сложность» определяется как сложность, которая не присуща проблеме, по сравнению с «существенной» сложностью. Методы, необходимые для «Укрощения», будут зависеть от того, с чего вы начнете. Следующее относится в основном к системам, которые уже приобрели ненужную сложность.
У меня есть опыт в ряде крупных многолетних проектов, в которых «случайный» компонент значительно перевешивал «существенный» аспект, а также те, в которых его не было.
На самом деле алгоритм Фейнмана в некоторой степени применим, но это не означает, что «мыслить по-настоящему» означает только магию, которую нельзя кодифицировать.
Я считаю, что есть два подхода, которые необходимо принять. Возьми их обоих - они не альтернативы. Одним из них является решение этого вопроса по частям, а другим - серьезная переделка. Поэтому, конечно, «запишите проблему». Это может принять форму аудита системы - модулей кода, их состояния (запах, уровень автоматизированного тестирования, количество сотрудников, которые утверждают, что понимают это), общей архитектуры (такая есть, даже если у нее «есть проблемы») ), состояние требований и т. д. и т. д.
Природа «случайной» сложности заключается в том, что нет ни одной проблемы, которая просто нуждается в решении. Так что нужно сортировать. Где это больно - с точки зрения способности поддерживать систему и прогрессировать ее развитие? Может быть, какой-то код действительно вонючий, но не является главным приоритетом, и исправление может быть подождать С другой стороны, может быть некоторый код, который быстро вернет время, потраченное на рефакторинг.
Определите план того, какой будет лучшая архитектура, и постарайтесь убедиться, что новая работа соответствует этому плану - это постепенный подход.
Кроме того, сформулируйте стоимость проблем и используйте это, чтобы построить экономическое обоснование, чтобы оправдать рефакторинг. Ключевым моментом здесь является то, что хорошо спроектированная система может быть гораздо более надежной и проверяемой, что приводит к гораздо более короткому времени (затратам и графику) для осуществления изменений - это имеет реальную ценность.
Серьезная переделка относится к категории «думай очень усердно» - ты должен сделать это правильно. Это то, где наличие «Фейнмана» (ну, в общем, небольшая его часть) действительно окупается. Крупная переделка, которая не приводит к улучшению архитектуры, может привести к катастрофе. Полное переписывание системы печально известны для этого.
Под любым подходом подразумевается умение отличать «случайное» от «существенного», то есть нужно иметь великого архитектора (или команду архитекторов), который действительно понимает систему и ее назначение.
Сказав все это, ключевым моментом для меня является автоматизированное тестирование . Если вам этого достаточно, ваша система находится под контролем. Если нет. , ,
источник
Позвольте мне набросать мой личный алгоритм для решения случайных сложностей.
Вся магия дизайна будет на шаге 3: как вы настраиваете эти классы? Это тот же вопрос, что и: как вы себе представляете, что у вас есть решение вашей проблемы, прежде чем у вас есть решение вашей проблемы?
Примечательно, что воображение, что у вас есть решение, кажется одной из главных рекомендаций людей, которые пишут о решении проблем («Абсельсон и Суссман,« Желаемое мышление »,« Структура и интерпретация компьютерных программ » и« Работа в обратном направлении »в книге Поли« Как Решить это )
С другой стороны, не у всех одинаковый « вкус к воображаемым решениям »: есть решения, которые только вы находите изящными, и есть другие, более понятные широкой аудитории. Вот почему вам необходимо провести рецензирование своего кода с другими разработчиками: не столько для настройки производительности, сколько для согласования понятных решений. Обычно это приводит к изменению дизайна и, после некоторых итераций, к гораздо лучшему коду.
Если вы придерживаетесь написания минимальных реализаций для прохождения ваших тестов и написания тестов, которые понятны многим, вы должны покончить с базой кода, где остается только неснижаемая сложность .
источник
Случайный Сложность
Первоначальный вопрос (перефразированный) был:
Случайная сложность возникает, когда те, кто руководит проектом, предпочитают добавлять технологии, которые являются единичными, и что общая стратегия первоначальных архитекторов проекта не намеревалась внедряться в проект. По этой причине важно записать обоснование выбора в стратегии.
Случайные сложности могут быть предотвращены руководством, которое придерживается своей первоначальной стратегии до тех пор, пока не станет очевидным необходимость преднамеренного отхода от этой стратегии.
Как избежать ненужной сложности
Исходя из основной части вопроса, я бы перефразировал это так:
Это перефразирование более уместно для основной части вопроса, где алгоритм Фейнмана был затем введен, предоставляя контекст, который предлагает, что для лучших архитекторов, когда они сталкиваются с проблемой, имеют гештальт, из которого они затем умело строят решение, и что остальные из нас не могут надеяться узнать это. Наличие гештальта понимания зависит от интеллекта субъекта и его готовности изучать особенности архитектурных опций, которые могут быть в их рамках.
Процесс планирования проекта будет использовать изучение организации, чтобы составить список требований проекта, а затем попытаться составить список всех возможных вариантов, а затем согласовать варианты с требованиями. Гештальт эксперта позволяет ему делать это быстро, и, возможно, с небольшим очевидным трудом, заставляя его казаться, что ему это легко дается.
Я утверждаю, что это приходит к нему из-за его подготовки. Для того, чтобы гештальт эксперта требовал знакомства со всеми вашими вариантами, а также дальновидность, чтобы обеспечить простое решение, которое учитывает прогнозируемые будущие потребности, которые, как определено, должен предусматривать проект, а также гибкость адаптации к меняющимся потребностям проект. Подготовка Фейнмана состояла в том, что он имел глубокое понимание различных подходов в теоретической и прикладной математике и физике. Он был врожденно любопытен и достаточно ярок, чтобы понять, что он обнаружил в окружающем его мире природы.
Опытный архитектор технологий будет проявлять аналогичное любопытство, опираясь на глубокое понимание основ, а также на широкое знакомство с большим разнообразием технологий. Он (или она) будет иметь мудрость, чтобы опираться на стратегии, которые были успешными в разных областях (например, Принципы программирования Unix ) и те, которые применяются к конкретным областям (например, шаблоны проектирования и руководства по стилю ). Он может быть не очень хорошо осведомлен о каждом ресурсе, но он будет знать, где его найти.
Построение решения
Этот уровень знаний, понимания и мудрости может быть извлечен из опыта и образования, но требует интеллекта и умственной деятельности, чтобы составить гештальт-стратегическое решение, которое работает вместе таким образом, чтобы избежать случайных и ненужных сложностей. Требуется, чтобы эксперт соединил эти основы; это были работники умственного труда, которых Друкер предвидел, когда впервые придумал этот термин.
Вернуться к конкретным заключительным вопросам:
Конкретные методы для укрощения случайных сложностей можно найти в следующих источниках.
Следуя принципам Unix-программирования, вы будете создавать простые модульные программы, которые хорошо работают и имеют надежные общие интерфейсы. Следующие шаблоны проектирования помогут вам создавать сложные алгоритмы, которые не сложнее, чем необходимо. Следуя Руководствам по стилю, вы убедитесь, что ваш код читабелен, удобен в обслуживании и оптимален для языка, на котором написан ваш код. Эксперты усвоят многие из принципов, найденных в этих ресурсах, и смогут объединить их в единую единую структуру.
источник
Возможно, это был сложный вопрос несколько лет назад, но сейчас ИМО уже не сложно устранить случайную сложность.
В какой-то момент Кент Бекс сказал о себе: «Я не отличный программист; я просто хороший программист с хорошими привычками».
IMO стоит подчеркнуть две вещи: он считает себя программистом , а не архитектором, и его внимание сосредоточено на привычках, а не на знаниях.
Способ решения сложных проблем Фейнманом - единственный способ сделать это. Описание не обязательно очень легко понять, поэтому я буду его разбирать. Голова Фейнмана была не просто полна знаний, она также была полна умения применять эти знания. Когда у вас есть знания и навыки для его использования, решить сложную проблему не сложно и не просто. Это единственный возможный результат.
Существует совершенно не магический способ написания чистого кода, который не содержит случайных сложностей, и он в основном похож на то, что делал Фейнман: приобретать все необходимые знания, тренироваться, чтобы привыкнуть применять его на практике, а не просто спрятать его в каком-то уголке своего мозга, затем напишите чистый код.
Теперь многие программисты даже не знают всех знаний, необходимых для написания чистого кода. Молодые программисты склонны отказываться от знаний об алгоритмах и структурах данных, а большинство старых программистов склонны забывать это Или большие обозначения O и анализ сложности. Старые программисты склонны отклонять шаблоны или запахи кода - или даже не знают, что они существуют. Большинство программистов любого поколения, даже если они знают о шаблонах, никогда не помнят точное, когда использовать и части драйверов. Немногие программисты любого поколения постоянно оценивают свой код на соответствие принципам SOLID. Многие программисты смешивают все возможные уровни абстракции повсюду. Пока я не знаю ни одного коллеги-программиста, который бы постоянно оценивал его код по отношению к запахам, описанным Фаулером в его книге по рефакторингу. Хотя в некоторых проектах используется какой-либо инструмент метрик, наиболее часто используемая метрика - это сложность того или иного типа, тогда как две другие метрики - связность и сплоченность - в значительной степени игнорируются, даже если они очень важны для чистого кода. Другим аспектом, который почти все игнорируют, является когнитивная нагрузка. Немногие программисты рассматривают юнит-тесты как документацию, и еще меньше знают, что трудно писать или называть юнит-тесты еще одной вонью кода, которая обычно указывает на плохой факторинг. Крошечное меньшинство знает о мантре управляемой доменом конструкции, чтобы держать модель кода и модель бизнес-домена как можно ближе друг к другу, поскольку несоответствия неизбежно создают проблемы в будущем. Все это необходимо учитывать постоянно, если вы хотите, чтобы ваш код был чистым. И многое другое, что я не могу вспомнить прямо сейчас. наиболее используемая метрика - это сложность того или иного рода, в то время как две другие метрики - связность и сплоченность - в значительной степени игнорируются, даже если они очень важны для чистого кода. Другим аспектом, который почти все игнорируют, является когнитивная нагрузка. Немногие программисты рассматривают юнит-тесты как документацию, и еще меньше знают, что трудно писать или называть юнит-тесты еще одной вонью кода, которая обычно указывает на плохой факторинг. Крошечное меньшинство знает о мантре управляемой доменом конструкции, чтобы держать модель кода и модель бизнес-домена как можно ближе друг к другу, поскольку несоответствия неизбежно создают проблемы в будущем. Все это необходимо учитывать постоянно, если вы хотите, чтобы ваш код был чистым. И многое другое, что я не могу вспомнить прямо сейчас. наиболее используемая метрика - это сложность того или иного рода, в то время как две другие метрики - связность и сплоченность - в значительной степени игнорируются, даже если они очень важны для чистого кода. Другим аспектом, который почти все игнорируют, является когнитивная нагрузка. Немногие программисты рассматривают юнит-тесты как документацию, и еще меньше знают, что трудно писать или называть юнит-тесты еще одной вонью кода, которая обычно указывает на плохой факторинг. Крошечное меньшинство знает о мантре управляемой доменом конструкции, чтобы держать модель кода и модель бизнес-домена как можно ближе друг к другу, поскольку несоответствия неизбежно создают проблемы в будущем. Все это необходимо учитывать постоянно, если вы хотите, чтобы ваш код был чистым. И многое другое, что я не могу вспомнить прямо сейчас. в то время как две другие метрики - связь и сплоченность - в значительной степени игнорируются, даже если они очень важны для чистого кода. Другим аспектом, который почти все игнорируют, является когнитивная нагрузка. Немногие программисты рассматривают юнит-тесты как документацию, и еще меньше знают, что трудно писать или называть юнит-тесты еще одной вонью кода, которая обычно указывает на плохой факторинг. Крошечное меньшинство знает о мантре управляемой доменом конструкции, чтобы держать модель кода и модель бизнес-домена как можно ближе друг к другу, поскольку несоответствия неизбежно создают проблемы в будущем. Все это необходимо учитывать постоянно, если вы хотите, чтобы ваш код был чистым. И многое другое, что я не могу вспомнить прямо сейчас. в то время как две другие метрики - связь и сплоченность - в значительной степени игнорируются, даже если они очень важны для чистого кода. Другим аспектом, который почти все игнорируют, является когнитивная нагрузка. Немногие программисты рассматривают юнит-тесты как документацию, и еще меньше знают, что трудно писать или называть юнит-тесты еще одной вонью кода, которая обычно указывает на плохой факторинг. Крошечное меньшинство знает о мантре управляемой доменом конструкции, чтобы держать модель кода и модель бизнес-домена как можно ближе друг к другу, поскольку несоответствия неизбежно создают проблемы в будущем. Все это необходимо учитывать постоянно, если вы хотите, чтобы ваш код был чистым. И многое другое, что я не могу вспомнить прямо сейчас. Другим аспектом, который почти все игнорируют, является когнитивная нагрузка. Немногие программисты рассматривают юнит-тесты как документацию, и еще меньше знают, что трудно писать или называть юнит-тесты еще одной вонью кода, которая обычно указывает на плохой факторинг. Крошечное меньшинство знает о мантре управляемой доменом конструкции, чтобы держать модель кода и модель бизнес-домена как можно ближе друг к другу, поскольку несоответствия неизбежно создают проблемы в будущем. Все это необходимо учитывать постоянно, если вы хотите, чтобы ваш код был чистым. И многое другое, что я не могу вспомнить прямо сейчас. Другим аспектом, который почти все игнорируют, является когнитивная нагрузка. Немногие программисты рассматривают юнит-тесты как документацию, и еще меньше знают, что трудно писать или называть юнит-тесты еще одной вонью кода, которая обычно указывает на плохой факторинг. Крошечное меньшинство знает о мантре управляемой доменом конструкции, чтобы держать модель кода и модель бизнес-домена как можно ближе друг к другу, поскольку несоответствия неизбежно создают проблемы в будущем. Все это необходимо учитывать постоянно, если вы хотите, чтобы ваш код был чистым. И многое другое, что я не могу вспомнить прямо сейчас. s мантра, чтобы держать модель кода и модель бизнес-домена как можно ближе друг к другу, так как расхождения неизбежно создадут проблемы в будущем. Все это необходимо учитывать постоянно, если вы хотите, чтобы ваш код был чистым. И многое другое, что я не могу вспомнить прямо сейчас. s мантра, чтобы держать модель кода и модель бизнес-домена как можно ближе друг к другу, так как расхождения неизбежно создадут проблемы в будущем. Все это необходимо учитывать постоянно, если вы хотите, чтобы ваш код был чистым. И многое другое, что я не могу вспомнить прямо сейчас.
Вы хотите написать чистый код? Там нет магии требуется. Просто изучите все, что требуется, затем используйте его, чтобы оценить чистоту вашего кода, и рефакторинг, пока вы не будете счастливы. И продолжайте учиться - программное обеспечение - все еще молодая область, и новые знания и знания приобретаются в быстром темпе.
источник