Статьи

3 основных программных принципа, которые вы должны понимать

Если вы занимаетесь разработкой программного обеспечения, постоянно появляются новые методы, языки и концепции. Мы все время от времени испытываем эти ноющие сомнения: «Могу ли я идти в ногу с изменениями и оставаться конкурентоспособным?» Уделите немного времени и подытожите строчку из моего любимого фильма «Касабланка»: «Фундаментальные вещи применяются со временем».

Переизданный учебник

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

Что верно для любви, верно для кода.

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


Основная стратегия снижения сложности до управляемых единиц состоит в том, чтобы разделить систему на части.

Этот принцип настолько важен для понимания, что я не напишу его дважды! На него обычно ссылается аббревиатура DRY, и он появился в книге Энди Ханта и Дейва Томаса «Прагматичный программист» , но сама концепция известна уже давно. Это относится к мельчайшим частям вашего программного обеспечения.

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

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

Разделив системы на компоненты и, далее, компоненты на подкомпоненты, вы достигнете уровня, на котором сложность сводится к одной ответственности. Эти обязанности могут быть реализованы в классе (мы предполагаем, что мы создаем объектно-ориентированное приложение). Классы
содержать методы и свойства. Методы реализации алгоритмов. Алгоритмы и — в зависимости от того, насколько одержим мы хотим получить — части
Алгоритмы вычисляют или содержат самые маленькие части, которые строят вашу бизнес-логику.

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

У них должно быть одно представление внутри.

Каждая часть знаний должна иметь одно, однозначное, авторитетное представление в системе.

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

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

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

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

DRY — это философия, которая упаковывает логику в представления.

Есть много способов достижения СУХОЙ. Хант и Томас предложили (среди прочего) генераторы кода и преобразование данных. Но, по сути, DRY — это философия, которая упаковывает логику в представления.

Поскольку каждая часть вашего приложения может рассматриваться как представление, каждая часть предоставляет конкретные фрагменты вашей базовой логики: управление пользователями предоставляет доступ зарегистрированным пользователям CMS, класс пользователя представляет одного пользователя и предоставляет его свойства (например, имя пользователя) , Он извлекает свойства через представление базы данных.

СУХАЯ и модульная архитектура требует хорошего планирования. Чтобы добиться иерархии представления снизу вверх, разделите ваше приложение на иерархически логически разделенные меньшие части и дайте им общаться друг с другом. Если вам нужно управлять более крупными проектами, хорошая идея организовать их по компонентам и использовать DRY внутри компонентов. Попробуйте применить следующие правила:

  • Создайте визуальную иерархию своего программного приложения и сопоставьте с ним основные компоненты. Для сложных проектов может потребоваться выделенная карта для каждого компонента.
  • Если вы достигаете уровня связанных обязанностей, вы можете переключиться на диаграммы UML (или аналогичные).
  • Прежде чем писать кусок кода, назовите его иерархию в программном проекте. Определите, что он представляет, и убедитесь, что вы знаете его роль в окружающем компоненте.
  • Определите, что представление должно предоставлять другим сторонам (например, функции для выполнения SQL в драйвере базы данных) и что оно должно скрывать (например, учетные данные базы данных).
  • Убедитесь, что представления не полагаются на представления другого уровня сложности (например, компонент, который опирается на класс в другом компоненте).

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

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

В реальном мире приложения, которые на 100% СУХИЕ, трудны, если не невозможны. Тем не менее, приложения, которые являются неприемлемыми в неприемлемой степени — и, следовательно, их трудно поддерживать — довольно распространены. Следовательно, не удивительно, что более 50% всех программных проектов терпят неудачу — если вы посмотрите на код.

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

Плохой код редко создается плохими кодерами.

СУХОСТЬ достигается хорошим планированием.

В качестве примера, скажем, вы наняли в качестве технического консультанта компанию, у которой есть проблемы с качеством кода и обслуживанием. Вы просматриваете исходный код и видите взломы и дублирование кода — код не СУХОЙ. Это признак плохого качества кода, а не причина. Если вы взглянете на систему контроля версий, то есть на историю кода, есть вероятность, что вы можете найти взломы, которые были введены иногда в сжатые сроки и вехи. Потратьте время, чтобы просмотреть, какие изменения внесены, и вы, вероятно, столкнетесь с изменением требований.

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

Есть причина, по которой самые успешные корпорации в ИТ-бизнесе были основаны людьми с очень хорошим техническим пониманием или даже самими их кодерами: Билл Гейтс, Марк Цукерберг, Стив Возняк, Стив Джобс, Ларри Пейдж, Сергей Брин и Ларри Эллисон знают (или знал) какие усилия нужны, чтобы что-то реализовать. Наоборот, многие компании стремятся передать требования к инжинирингу в руки менеджеров по работе с клиентами, а концептуальную часть — в руки бизнес-консультантов … людей, которые никогда ничего не реализовывали.

Следовательно, многие технические концепции работают только в Powerpoint, Photoshop и на 27-дюймовых широкоэкранных дисплеях. Возможно, это был успешный подход во времена, более или менее, статических веб-сайтов, но сейчас это не так — с интерактивными приложениями на нескольких устройствах. Поскольку кодеры являются последними в очереди, именно они должны применять быстрые исправления ошибок в концепции. Если это сопровождается менеджером по работе с клиентами, который не может противостоять клиенту, который любит делать в последнюю минуту Изменения, планы выбрасываются в мусорное ведро, и что-то быстрое и грязное реализуется. Код становится unDRY.

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

Если у вас есть невмешательство, продолжайте читать! Вы не нуждаетесь в этом, принцип придет на помощь.


Самое простое объяснение имеет тенденцию быть правильным.

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

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

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

Значительный прогресс в истории человечества был достигнут латеральными мыслителями.

Протокол передачи гипертекста широко считается идеальным примером для простого решения: он предназначен для передачи документов на основе гипертекста, в настоящее время он является основой очень интерактивных и настольных приложений. Может быть, мы должны найти решения для ограничений в протоколе, и, возможно, нам придется заменить его когда-нибудь. Однако статус-кво: на основе нескольких методов запроса (таких как GET и POST), кодов состояния и аргументов в виде простого текста HTTP доказал свою гибкость и надежность. Вот почему HTTP неоднократно выдвигался до предела веб-разработчиками — и все еще стоит.

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

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

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

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

Однажды я работал над проектом, в котором клиент хотел импортировать электронные таблицы Excel в свою программу управления командой. Это было четкое совпадение. Excel является проприетарным программным обеспечением со сложным форматом документов. Формат сложный, потому что он многофункциональный: в него можно добавлять графики и другие вещи — функции, которые не нужны клиенту. Его просто интересовали цифры. Таким образом, реализация импорта в Excel потребует много ненужных функций. Кроме того, существует несколько версий версий Excel, и Microsoft выпускает еще один выпуск каждый год. Это было бы трудно поддерживать, и это сопряжено с дополнительными расходами в будущем.

В итоге мы осуществили импорт через запятую. Это было сделано с помощью нескольких строк кода. Затраты на данные были очень небольшими (сравните таблицу Excel с ее CSV-эквивалентом), и решение было легко обслуживаемым и перспективным. В любом случае Excel был готов экспортировать CSV (а также другие программы, которые клиент может захотеть использовать в будущем). Поскольку решение также было недорогим, это было хорошее применение принципа KISS.

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


Кодирование — это создание вещей.

Когда Google+ запустил, Марк Цукерберг — основатель Facebook — был одним из первых, кто создал аккаунт в социальной сети, который стремился уничтожить его. Он добавил всего одну строчку в раздел « Обо мне »: «Я строю вещи». Я искренне думаю, что это блестящее предложение, потому что оно описывает чистую суть кодирования в нескольких простых словах. Почему вы решили стать кодером? Увлечение техническими решениями? Красота эффективности? Каким бы ни был ваш ответ, это может быть не « создание 1.000.001-го корпоративного веб-сайта со стандартной функциональностью» . Однако большинство из нас так зарабатывают. Независимо от того, где вы работаете, вы, вероятно, время от времени будете сталкиваться с скучными и повторяющимися задачами.

80% времени, затрачиваемого на программный проект, инвестируется в 20% функциональности.

Принцип « Я тебе не понадоблюсь» (ЯГНИ) решает эти задачи. Это в основном означает: если это не в концепции, это не в коде. Например, обычной практикой является абстрагирование доступа к базе данных на уровне, который обрабатывает различия между различными драйверами, такими как MySQL, PostgreSQL и Oracle. Если вы работаете на корпоративном веб-сайте, который размещен в стеке LAMP, на общем хосте, насколько вероятно, что они изменят базу данных? Помните, что концепция была написана с учетом бюджета.

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

Вы, возможно, заметили разницу между тем, что Вам это не понадобится, и модульными архитектурами, основанными на технологии DRY : последняя уменьшает сложность, разделяя проект на управляемые компоненты, тогда как первая уменьшает сложность, уменьшая количество компонентов. YAGNI похож на принцип KISS , так как он стремится к простому решению. Тем не менее, KISS стремится к простому решению, пытаясь реализовать что-то настолько легко, насколько это возможно; YAGNI стремится к простоте, не применяя ее вообще!

Теодор Осетр , американский писатель-фантаст, сформулировал закон: « Девяносто процентов всего дерьма» . Это очень радикальный подход, и он не слишком полезен в реальных проектах. Но имейте в виду, что «дерьмо» может быть очень трудоемким. Хорошее практическое правило: примерно 80% времени, затрачиваемого на программный проект, инвестируется в 20% функциональности. Подумай о своих проектах! Каждый раз, когда я это делаю, я удивляюсь точности правила 80:20.

80% времени, затрачиваемого на программный проект, инвестируется в 20% функциональности.

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

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

Когда вы готовите свой список дел для проекта, подумайте над следующими соображениями:

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

Давайте углубимся в детали! Я уже представил пример для первого элемента в списке: не оборачивайте драйвер базы данных вокруг слоя абстракции базы данных. С подозрением относитесь ко всему, что добавляет сложности вашему программному стеку. Обратите внимание, что абстракция часто предоставляется сторонними библиотеками. Например, в зависимости от вашего языка программирования, уровень персистентности, такой как Hibernate (Java), Doctrine (PHP) или Active Record (Ruby), поставляется с абстракцией базы данных и объектно-реляционным отображением. Каждая библиотека добавляет сложности. Это должно быть поддержано. Обновления, патчи и исправления безопасности должны быть применены.

Мы реализуем функции каждый день, потому что ожидаем, что они будут полезны. Следовательно, мы думаем заранее и реализуем слишком много. Например, многие клиенты хотят иметь мобильный сайт. Мобильный это термин широкого понимания; это не дизайнерское решение. Это случай использования! Люди, которые используют мобильный сайт, ну, в общем, мобильные. Это означает, что они могут захотеть получить доступ к другой информации или функциям, чем пользователь, который посещает сайт, лежащий на его рабочем столе. Подумайте о кинотеатре: пользователи автобуса, скорее всего, захотят получить доступ к времени начала предстоящих фильмов, а не к трейлеру объемом 50 МБ.

Плохие концепции часто можно определить по отсутствию нефункциональных требований.

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

Нефункциональные требования не описывают поведение программного обеспечения, они описывают дополнительные свойства, которые можно использовать для оценки качества программного обеспечения. Поскольку описание качества программного обеспечения предполагает знание программного обеспечения, плохие концепции часто можно определить по отсутствию нефункциональных требований. Поддержка, уровень документации и простота интеграции являются примерами нефункциональных требований. Нефункциональные требования должны быть измеримыми. Следовательно, »страница должна загружаться быстро.« Слишком не конкретна », страница должна загружаться максимум через две секунды во время теста средней производительности.« Очень конкретна и измерима. Если вы хотите применить принцип YAGNI, примите умеренные нефункциональные требования, если они не упомянуты в концепции (или если они упоминаются, но не конкретны). Если вы сами пишете нефункциональные требования, будьте реалистичны: небольшая корпорация с 20-50 посещениями страниц в день не требует трехдневной настройки производительности — поскольку страница должна загружаться достаточно быстро, поскольку сервер не занят. Если корпорация может увеличить количество ежедневных посещений, лучший сервер или пакет хостинга не должен быть слишком дорогим.

И последнее, но не менее важное: помните эмпирическое правило 80:20!

И последнее, но не менее важное: помните эмпирическое правило 80:20! Мы должны определить трудоемкие детали. Если какая-то часть абсолютно необходима, вы должны выполнить ее. Вопрос должен быть: как вы это осуществите? Это должна быть последняя структура с небольшим сообществом? Вам нужно переключиться на только что выпущенную версию библиотеки, если документация не обновлена? Стоит ли использовать новую CMS, когда не все расширения доступны? Сколько исследований потребуется для этого? «Так мы всегда это делали.« Это не захватывающий подход, но он сделает работу без сюрпризов.

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

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

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

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


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