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

Позвольте мне сначала рассказать вам небольшую историю о том, как я усвоил эти уроки.

Несколько лет назад я поставил перед собой задачу создать приложение для расчета конструкций, предназначенное для студентов инженерных специальностей и архитекторов. Я хотел расти как инженер-программист, а также продемонстрировать потенциальным работодателям, что у меня есть все необходимое, чтобы стать хорошим профессионалом в области программного обеспечения. Результатом стало InkStructure, собственное приложение OSX, написанное на Swift с использованием родного Какао-фреймворка. Когда я его выпустил, он получил относительно теплый прием.

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

Благодаря этому ретроспективному упражнению и некоторым дополнительным годам опыта я в настоящее время переписываю все приложение, и вот как оно выглядит сегодня (еще не выпущено):

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

«Знание» без практического опыта - это лишь частичное знание: человек учится на практике. Самостоятельно совершать ошибки и страдать от последствий - ваш лучший учитель.

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

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

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

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

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

Да, вы можете делать это для развлечения, для удовольствия или исключительно ради изучения новой технологии, языка или фреймворка. Но чтобы создать хорошее программное обеспечение, программное обеспечение, которое могло бы попасть в категорию полезных, оно сначала должно удовлетворять потребности реальных пользователей (мне сказали, что Amazon называет это« обратным ходом ). А чтобы узнать, какие архитектурные решения работают, а какие нет, вам нужно передать их пользователям, исправить беспокоящие их ошибки и добавить необходимые им функции. Хорошо ли уместился в вашем коде с этими изменениями?

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

Когда я начал работать над своим приложением InkStructure, я был слишком сосредоточен на технической части проекта: весь мой код имел 80% тестовое покрытие, я везде придерживался шаблонов проектирования, весь код был распределен в слабо связанных модулях (не правда, но так я думал)… но я упустил эту очень важную предпосылку; Я принимал во внимание потребности своих пользователей только после того, как программное обеспечение было полностью завершено и архитектурно превосходно. Большая ошибка! Я нашел, как удовлетворить то, что пользователи хотят делать с моим программным обеспечением, мне нужно было внести большие изменения, которые сломали, казалось бы, несвязанные части приложения; моя возвышенная архитектура разваливалась на части.

Одним из примеров того, что требовалось пользователям, и я не мог удовлетворить их, были новые инструменты, которые позволяли им изменять геометрию более продвинутыми способами, например перемещать структурные узлы или добавлять сосредоточенные нагрузки на структурные элементы. То, как я решил обрабатывать события мыши для выбранного инструмента, не масштабировалось; позволь мне объяснить.

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

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

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

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

Я написал книгу, которая уже находится в предварительной продаже (взгляните сюда), ууу! В этой книге я обобщаю наиболее важные уроки работы в приложении InkStructure. Книга предназначена для тех инженеров, которые хотят работать над написанием приложений, решающих проблемы машиностроения / гражданского строительства. Если вы хотите узнать об этом больше или высказать свое мнение по этому поводу, не стесняйтесь обращаться ко мне.