главный архитектор интел программный код будет на русском
Киселев назвал российское образование «конвейером, создающим недовольных»
Телеведущий Дмитрий Киселев объяснил возникновение протестных настроений в России системой высшего образования, которую он назвал «конвейером, создающим недовольных». Об этом он заявил в программе «Вести недели» в эфире телеканала «Россия 1». Запись опубликована в YouTube телеканала.
Недовольных, по словам Киселева, особенно много среди студентов гуманитарных вузов. Гуманитариев, как считает телеведущий, «слишком много для страны», а процесс их обучения недостаточно «напряжен и насыщен, чтобы уберечь от глупостей».
В качестве примера он привел двух студенток факультета журналистики МГУ «с академическими задолженностями», которые выступают в защиту аспиранта вуза Азата Мифтахова. По словам Киселева, организовать группу поддержки Мифтахова им мешают «хвосты» по учебе. «Просто учиться не хочется, скучно. Куда веселее, как представляется студенткам-гуманитариям, политический активизм», — заявил Киселев.
Он также отметил, что «для кого-то «производство гуманитариев» — бизнес». Для студентов и их родителей обучение в гуманитарных вузах, по мнению телеведущего, — большие затраты и надежда на образование, тогда как для выпускников — «сверхожидание и сверхамбиции». «А потом сверхожидания оборачиваются разочарованием, а сверхамбиции — обидой и недовольством к стране и обществу, мол, ко мне несправедливы, а значит, и общество несправедливо, точнее власть».
Киселев добавил, что у кого-то недовольство возникает еще до окончания вуза. «Вместо того чтобы учиться, куда интереснее самоутверждаться протестом Итак, выходит, что у нас система высшего образования — конвейер, создающий недовольных», — заключил телеведущий.
Профессия «Архитектор программного обеспечения» — подробное описание и обзор
Программное обеспечение или сокращённо ПО — это все те программы, с помощью которых пользователи управляют персональным компьютером и решают свои задачи. Проще говоря, чтобы написать текст в Word или составить расчётную таблицу в Excel, вам нужно открыть эти программы на компьютере, ввести текст или цифры. Результат, который вы увидите на экране монитора, возможен благодаря этому самому ПО.
Советуем обратить внимание на топовую подборку курсов для архитекторов программного обеспечения
Существует системное и прикладное программное обеспечение, каждое имеет свои характеристики и применение. Прикладное ПО позволяет составлять различные документы, презентации, просматривать видео и слушать музыку. Системное — это операционная система и драйверы, они управляют компьютером и позволяют, например, установить новые программы. Специалисты, которые разрабатывают такие ПО, называются программистами. А те, кто проектируют структуру и составляют для них техническое задание — архитекторами программного обеспечения.
Архитектор ПО: кто это и чем занимается
Архитектор программного обеспечения — это опытный программист, который занимается проектированием ПО, создаёт её архитектуру, определяя внутреннюю систему и внешний вид. Обычно такой специалист начинает свою профессиональную деятельность с позиции системного администратора или программиста. Постепенно наращивая свой опыт и знания, он детально осваивает весь процесс разработки. Благодаря комплексному пониманию ПО и бизнес-процессов, архитектор занимает важную роль в компании. Разберём подробнее его задачи по направлениям.
Основные задачи:
Возможные направления работы: крупные IT-компании, бизнес.
Что должен знать и уметь архитектор ПО
Технические руководителей IT-проекта имеют много обязанностей, но в основном они должны уметь:
Личные качества
Системный архитектор обладает следующими качествами:
Базовые настройки любого сотрудника:
Разные стороны профессии
Инженер программного обеспечения, как и любая другая специальность, имеет особенности.
Зарплата в Москве и по России
Средний заработок системного архитектора в Москве можно увидеть на скриншоте с сайта trud.com за 2019/2020 год:
Средняя зарплата в регионах:
Зарплата, указанная в вакансиях профессии «архитектор программного обеспечения», начинается от 70 тыс. руб. согласно сайту hh.ru. Начинающий проектировщик ПО должен:
Зарплата в 100-150 тыс. руб. предлагается специалисту среднего уровня, с опытом работы больше 1-3 года. Перечень некоторых его задач:
Проектировщик ПО с опытом более 3-х лет зарабатывает от 150 тыс. руб. Помимо основных технических обязанностей, он должен руководить командой и иметь определенные личностные качества. Требования работодателей к такому профессионалу:
Как стать архитектором программного обеспечения
Эта профессия востребованная, что делает её высокооплачиваемой и очень престижной. Но высокий заработок предполагает высокий уровень знаний, опыта и ответственности. Самостоятельно стать инженером ПО не получится, т. к. для этого требуется иметь много различных навыков, начиная с базового уровня программирования, заканчивая управленческой сферой. Без активной поддержки наставников не обойтись. Лучшим способом получения этой профессии станет комплексное обучение.
Один из вариантов — это профессиональное образование в вузе. Но есть вероятность, что большая часть времени будет потрачена на теорию, т. к. такие учреждения делают упор именно на неё. Практику придётся нарабатывать уже после выпуска, что будет проблематично. Не каждый работодатель готов принять сотрудника, не имеющего практических навыков. График занятий тоже не всегда удобен, что грозит пропусками и невозможность хорошо усвоить материал.
Есть способ проще и быстрее получить новую специальность → онлайн-курсы архитектора ПО.
С их помощью овладеть профессией на практике можно в дистанционном формате. Преимущества таких программ:
Если вас заинтересовала эта профессия — ставьте плюс в комментариях, расскажем, как в ней легко стартануть 🙂
Не знаете с чего начать?
Получите персональный список курсов, пройдя бесплатный тест по карьере
Проекты Центра разработки Intel в России. OpenVINO Toolkit
Выполняя свое обещание, в новом году мы продолжаем публикацию статей из рубрики «Проекты Центра разработки Intel в России». Эта серия посвящена относительно молодому, но уже получившему заслуженную популярность набору инструментов для разработки программ, использующих машинное зрение и Deep Learning — Open Visual Inference & Neural Network Optimization toolkit или, коротко, OpenVINO.
На наши вопросы об истории и сущности проекта ответил его главный архитектор Юрий Горбачев.
Юрий уже захаживал к нам в рубрику «Задайте вопрос эксперту Intel» — тогда мы говорили о Deep Learning вообще и OpenVINO в частности. Сейчас у нас есть возможность узнать больше подробностей о проекте.
Но сначала хотели бы повторить наш анонс. Начиная с 10 февраля для опытных разработчиков мы предлагаем участие во втором сезоне открытых вебинаров по компьютерному зрению, глубокому обучению и оптимизации CV Academy 2020-21 от подразделения Intel IOTG Computer Vision / IOTG Russia. Регистрация на второй сезон CV Academy открыта уже сейчас. Материалы вебинаров первого сезона доступны по ссылке.
А теперь целиком и полностью переключаемся на OpenVINO.
Итак, когда и как всё началось?
У OpenVINO достаточно интересная история. Изначально компания Intel работала над продуктом для решения задач компьютерного зрения через классические алгоритмы под названием Computer Vision SDK. Продукт был в основном направлен на ускорение приложений на акселераторах и графических картах. На это решение уже были определённые заказчики и велась работа по реализации настоящих приложений с его использованием.
Примерно в 2016 году стало понятно, что Deep Learning переходит в категорию прикладных технологий и при этом достигает значительно более высокого качества, чем классические алгоритмы. Многие задачи с точки зрения разработчика с его помощью решались значительно проще. Именно тогда было принято решение сфокусироваться на исполнении нейронных сетей, Computer Vision SDK в старом его виде перестал развиваться и уступил место новому продукту — OpenVINO.
В мае 2018 года на Embedded Vision Alliance Summit состоялся первый официальный и полноценный релиз OpenVINO и именно май мы считаем днём его рождения. Ну а возраст отсчитывается от момента первого полноценного релиза, так что скоро нам будет 3 года. Конечно, первые заказчики начинали пользоваться ещё Beta версиями OpenVINO и мы получали отзывы до полного релиза.
Первый анонс OpenVINO на Embedded Vision Alliance Summit. 2018 год
Надо сказать, что мы подошли к первому релизу в достаточно неплохой форме – поддерживали и валидировали десятки публичных сетей на CPU, GPU & VPU и могли переключаться между платформами практически без изменения кода приложения. На тот момент для многих аппаратных платформ Intel фактически не было решения, которое могло бы выполнять инференс всех этих сетей с подобной производительностью. Были, конечно, и недостатки, мы о них знали, планировали и прорабатывали решения.
Какие именно цели и задачи были поставлены? Насколько удалось их выполнить?
Изначальной целью было достичь наилучшей производительности и покрытия именно в инференсе нейронных сетей. Мы специально не рассматривали тренировку как функциональность продукта. Этот фокус и по сей день позволяет нам применить ряд оптимизаций и выигрывать в производительности, размере и другим характеристикам у других решений на платформе Intel.
Презентация OpenVINO в Китае — как положено, на чистом китайском. 2019 год
Intel предоставляет несколько платформ, способных запускать нейронные сети. У каждой платформы есть свои особенности и преимущества. К примеру, CPU – это достаточно распространённая платформа с возможностями ускорения сетей, но при этом все приложения работают на ней же. VPU – это ускоритель с малым энергопотреблением и целью именно ускорять сети. Соответственно, в зависимости от задачи, разработчик решения может выбирать. Мы же хотели сделать решение, при котором само приложение придётся менять минимально. В идеале, разработчик должен только указать на каком устройстве запускаться. Именно это мы и предоставляем по сей день.
Отдельно хочется отметить, что мы хотели устранить зависимости от сторонних программных продуктов, уменьшить размер, потребление памяти и других ресурсов. И таких целей мы достигли и продолжаем улучшения в этих областях.
Чему и как приходилось учиться в ходе работы? Какие возникали проблемы и как вы их решали?
После полноценного релиза продукта у нас появился достаточно большой объём отзывов и запросов на функциональность. Были вещи, связанные с поддержкой новых операций и сетей, были запросы на новые возможности в самом фреймворке. Некоторое время спустя мы добавили поддержку Altera FPGA как платформы, что само по себе был достаточно большой объём работы.
Пожалуй, одна из вещей, которую мы сразу осознали – разрыв между академической работой, которая проводится в области Deep Learning и реальным применением технологий в приложениях. Важнейшая цель исследований — улучшение качества того или иного решения и его победа в различного рода сравнительных тестах. Результаты такой работы часто бывает очень затруднительно использовать практически. Скажем, вполне нормальным считалось увеличить сеть в несколько раз в размерах и при этом достичь всего лишь процента улучшения. Использовать такие сети в реальных приложениях очень сложно.
Поэтому у нас появилась библиотека Open Model Zoo, где мы стали готовить модели для определённых задач и выкладывать их бесплатно для разработчиков. Модели достигали высокого качества, и при этом их производительность была на порядки выше академических. Для некоторых приложений достаточно было взять готовую модель из нашей библиотеки. Для этого мы приобретали данные, размечали и работали над компактными архитектурами сетей. Также мы стали выкладывать тренировочный код этих моделей для тех, кто хотел бы натренировать их на своих данных.
Юрий Горбачев и исполнительный директор Intel Боб Сван
Позднее мы перенесли фокус на оптимизации сетей посредством квантизации и других методов. Это стало возможным благодаря появлению новых наборов инструкций CPU или возможностей ускорения. Была проделана большая работа по созданию алгоритмов квантизации, которые оптимизируют сети уже после тренировки. При этом качество квантизации – лишь один аспект оценки нашего решения. Мы также хотели решить задачу удобства для пользователя. Ввели несколько режимов, при которых пользователь может выбирать между качеством или производительностью, квантизовать без использования аннотированного датасета и прочие упрощающие жизнь вещи.
Именно оптимизация сетей стала следующим качественным шагом в развитии OpenVINO. На новых платформах мы можем получать существенные ускорения именно за счёт этих методик. Работа продолжается и сейчас – мы разрабатываем Neural Network Compression Framework, позволяющий оптимизировать модели уже на этапе тренировки и выполнять не только квантизацию, но и прунинг сетей практически без потери качества. И наши результаты не ограничиваются только программными продуктами, мы стараемся публиковать статьи и различные посты в блогах, чтобы рассказывать о том, что и как мы делаем.
Мы постоянно работаем над документацией, семплами и демо для наших пользователей-разработчиков. Как один из основных инструментов для начинающих мы выпустили и улучшаем DL Workbench. Это визуальный продукт, позволяющий загрузить свою сеть и посмотреть результаты её работы, профилировать на реальной платформе, квантизовать и померять аккуратность инференса. Ее основной плюс состоит именно в том, что многие вещи не требуется делать через командную консоль и визуальность. Тут у нас большое количество планов, хотелось бы ещё больше функциональности добавить поскорее.
Нижегородская команда OpenVINO/IOTG Computer Vision. 2019 год
Откуда взялась команда проекта, как её набирали, сколько в ней было человек?
OpenVINO – это очень большая команда, находящаяся в нескольких географических зонах. Основной костяк команды сформировался сразу после покупки компании Itseez в Нижнем Новгороде. Компания Itseez работала с Intel и до этого над CV SDK, но после покупки мы сосредоточились именно над OpenVINO. Это было порядка 100 человек разной направленности: разработчики алгоритмов, оптимизаторы и инженеры-программисты. Команда очень много работала с заказчиками над продуктами, поэтому это было уникальное сочетание исследовательского опыта и опыта создания реальных продуктов. Думаю, именно поэтому мы смогли сформулировать стратегически верное направления для продукта и реализовать его.
Чем можно гордиться вам лично и вашей команде? Как вы лично для себя понимали, что успех, а что – не очень?
Мне кажется, гордиться в первую очередь можно тем, что мы создали и продолжаем разрабатывать востребованный у заказчиков продукт. И это не та ситуация, когда альтернативы нет. Мы постоянно улучшаемся, работаем над новой функциональностью и поддержкой новых платформ. Интересно видеть, как некоторые программные решения других компаний сейчас проходят по нашему пути.
В качестве оценки успешности мы ориентируемся на наших разработчиков и заказчиков. В принципе, у нас достаточно здоровый рост в их количестве, мы видим, что разработчики регулярно обновляют версию и пользуются новой функциональностью. Не могу сказать, что мы достигли точки, когда количество запросов на новые фичи замедлилось. Год назад команда OpenVINO получила Intel Achievement Award – высшая награда на уровне компании.
Получение Intel Achievement Award командой лидеров OpenVINO, 2019 год
Знаете ли вы про какие-нибудь экзотические, экстремальные случаи использования OpenVINO, про которые хочется рассказать?
Случаев таких много. Есть, к примеру, заказчики из исследовательских областей, использующие OpenVINO в расшифровке генома, решении задач подбора лекарств или постановки диагноза. Для нас это очень интересные задачи в первую очередь по причине огромного объёма обрабатываемых данных. Приведу такой пример из разряда best practice: при решении своей задачи заказчик использовал кластер серверов, а, перейдя на OpenVINO, смог ограничиться одним сервером.
Недавно был продукт для исследования морского дна, некий подводный дрон для наблюдения за кораллами. Ускорители сетей Intel использовались на спутниках для обработки изображений до их отправки.
OpenVINO — открытый проект, соответственно, интересует роль community. Как велик вклад в него сторонних разработчиков?
Мы полноценно стали разрабатывать в open source примерно полгода назад. За это время у нас появились сторонние разработчики, но я бы сказал, что самое интересное ещё впереди. Мы вносим очень много изменений внутри продукта и отслеживать их не всегда просто. Тут мы стараемся быть более открытыми – работаем над документацией, планируем публиковать наши планирующиеся улучшения и предлагать простые задачки для тех, кто хочет втянуться в процесс. До этого момента мы получали доработки в основном от компаний-заказчиков. И именно для них open source оказался очень успешным подходом, ведь они имеют возможность изменить тот или иной компонент под свой продукт.
И, напоследок, традиционный вопрос про творческие планы.
Сейчас у нас в работе платформы с Advanced Matrix Extension. Это новый набор инструкций, при котором можно ожидать очень существенного ускорения запуска сетей. Также готовится к выходу платформа Alder Lake с гибридным набором ядер, тут задача просто очень интересная технически – планирование выполнения на больших и маленьких ядрах.
Архитектор ПО: зачем он нужен и в чём его проклятие
Гость нового выпуска подкаста «Сушите вёсла» — архитектор программного обеспечения Егор Тафланиди. Обсуждаем, что это за метафизическая роль такая, какие сложности есть в работе и при чём тут тёмные силы.
Артём Кулаков и Рома Чорыев — разработчики Redmadrobot. Они записывают ламповые подкасты, где вместе с гостями обсуждают разные стороны создания ИТ-продуктов. Ниже ссылка на новый выпуск и ответы на несколько насущных вопросов.
Тайминг
01:40 Егор рассказывает, как стал архитектором
12:40 Популярные мифы: архитектор — высшая ступень развития разработчика; архитектор знает всё лучше всех и больше всех; архитектор не пишет код (потому что забыл как это делать); архитектор сидит и рисует какие-то схемы
31:20 Рассуждения о современных языках программирования
39:10 System/Solution/etc Architect. Что это вообще всё значит?
47:50 Обсуждение того самого «проклятия»
50:24 Как стать архитектором (warning: немного шуток)
55:16 Time management: один рабочий день архитектора — что он делает?
01:03:39 Какие есть сложность в работе и как их преодолеть
01:13:49 А что дальше: какие есть векторы развития
01:26:59 Ответ на вопрос: какой же true way для архитектора?
Кто такой архитектор ПО?
Архитектор — специалист, который занимается построением ИТ-систем для решения бизнес-задач. Он хорошо разбирается во всех нюансах проектирования систем.
Если нужно разработать, например, приложение, то архитектор расскажет, как это сделать, не наступив на грабли. Объяснит, какие технологии использовать, с какими проблемами можно столкнуться, и заложит фундамент для развития проекта. Авиационный конструктор решает, из чего построить самолёт, а архитектор — с помощью каких технологий разработать IT-систему, которая решит задачу.
Архитектор должен разбираться во всём?
В разговоре выяснилось, что это выходит само собой. Архитектор задействован в разных ситуациях: он общается с заказчиком, решает инженерные проблемы и даже участвует в планировании проекта. Хочешь не хочешь — а в бизнес углубляешься и менеджерский навык качаешь. Егор объясняет:
— Вся сущность сводится к двум вещам: архитектор должен решать задачи бизнеса и он должен уводить систему от ограничений. Если ты знаешь, что в системе нет физической возможности реализовать те или иные вещи, но есть бизнес-потребность, то твоя задача — придумать как и состыковать всё воедино. Можно сказать: сделать так, чтобы и овцы были целы, и волки сыты.
За день через архитектора проходит огромное количество информации от менеджеров, разработчиков, заказчиков. Поэтому под конец дня получается, что он знаком с ситуацией с разных сторон. Артём резюмировал:
— Архитектор — это больше про ширину, чем про глубину. Например, тебе необязательно уметь в Android работать с рефлексией и с какими-то низкоуровневыми вещами, но важно понимать, как всё это работает в целом.
Пишет ли архитектор код?
Если коротко, то некоторые архитекторы кодят. Подробнее об этом — в пятиминутном рассуждении в подкасте, начиная с 22:25. Спойлер: там про идеальный код, проблемы перфекциониста и бизнес-требования.
Как стать архитектором?
Опираясь на свой опыт, ребята рассказали, что просто перейти из разработчиков в архитекторы не получится. Сначала должна появиться необходимость в этой позиции. Только потом на неё подбирают человека из команды или зовут специалиста со стороны.
— У нас было так: компания развивалась, росло количество людей и проектов. Качество нужно было поддерживать, поэтому настал момент, когда появилась свободная «ниша ответственности».
Архитектор — высшая ступень разработчика?
В студии согласились с тем, что это определённо веха в развитии разработчика. Но не стоит воспринимать архитектора, как улучшенную версию «сеньора». Егор пояснил, что архитектор — это не финал и не потолок. У такого специалиста есть сильный навык решать инженерные задачи, поэтому вариантов для развития много. Например, можно перейти в IoT, заняться проектированием языков программирования или уйти в смежную область.
А что за «проклятие»?
Так объясняет этот феномен Егор:
— «Проклятие» заключается в том что, когда появляется необходимость в архитекторе, и человек занимает эту должность, то в этой компании больше никто не может стать архитектором.
Он рассказал, что специалист, занявший должность, вряд ли сможет заняться чем-то другим в дальнейшем (в рамках компании). Это связано с тем, что тяжело «воспитать» себе заместителя. Так получается по разным причинам: задачи архитектора сложно делегировать, не всегда есть человек, желающий встать на замену и просто не хватает времени для обучения.
Слушайте подкаст на удобной платформе — SoundCloud, Apple, Google Podcasts.
Полезные ссылки
Важные статьи, видео и книги для тех, кто хочет трансформироваться в архитектора:
Архитектура кода
В этой статье я хочу поделиться своим личным опытом, связанным с правильной организацией кода (архитектурой). Правильная архитектура существенно упрощает долгосрочную поддержку.
Это очень философская тема, поэтому я не могу предложить ничего более, чем мой субъективный анализ и опыт.
Проблемы, симптомы
Мой начальный опыт программиста был весьма безоблачным – я без лишних проблем клепал вебсайты-визитки. Писал код, как я это сейчас называю “в строчку” или “полотном”. На маленьких объемах и простых задачах все было хорошо.
Но я сменил работу, и пришлось разрабатывать один единственный вебсайт в течение 4-х лет. Естественно, сложность этого кода была несопоставима с визитками из моей прошлой работы. В какой-то момент проблемы просто посыпались на меня – количество регрессии зашкаливало. Было ощущение, что я просто хожу по кругу – пока чинил “здесь”, сломал что-то “там”. И поэтом это “здесь” и “там” банально менялось местами и круг повторялся.
У меня исчезла уверенность в том, что я контролирую ситуацию – при всем моем желании недопустить баги, они проскакивали. Все эти 4 года проект активно разрабатывался – мы улучшали уже существующий функционал, расширяли, достраивали его. Я видел и чувствовал, как удельная стоимость каждого нового рефакторинга/доработки растет – увеличивался общий объем кода, и соответственно увеличивались затраты на любую его правку. Банально, я вышел на порог, через который уже не мог переступить, продолжая писать код “в строчку”, без использования архитектуры. Но в тот момент, я этого еще не понимал.
Другим важным симптомом оказались книги и видео-уроки, которые я в то время читал/смотрел. Код с этих источников выглядел “глянцево” красивым, естественным и интуитивно понятным. Видя такую разницу между учебниками и реальной жизнью, моей первой реакцией была мысль, что это нормально – в жизни всегда сложнее, чем в теории, больше рутины и конкретики.
Тем не менее, продукт на работе нужно было расширять, улучшать, в общем, двигаться дальше. В тот же самый момент я начал активно участвовать в одном open source проекте. И в совокупности эти факторы вытолкнули меня на путь архитектурного мышления.
Что такое архитектура?
Один мой преподаватель в университете употребил фразу “нужно проектировать так, чтобы максимизировать количество объектов и минимизировать количество связей между ними”. Чем дольше я живу, тем больше с ним соглашаюсь. Если присмотреться к этой цитате, то видно, что эти 2 условия в какой-то мере взаимоисключающие – чем больше мы дробим какую-то систему на подсистемы, тем больше связей придется вводить между ними, чтобы “соединить” каждую из подсистем с остальными актерами. Найти оптимальный баланс между первым и вторым – это своего рода искусство, которым, как и прочими искусствами, можно овладеть через практику.
Сложная система дробится на подсистемы за счет интерфейсов. Для того, чтобы выделить из сложной системы какую-то подсистему, нужно определить интерфейс, который будет декларировать границы между первым и вторым. Представьте, у нас была сложная система, и вроде бы внутри нее осязаются некоторые подсистемы, но они “размазаны” по разным местам основной системы и четкий формат (интерфейс) взаимодействия между ними отсутствует:
Посчитаем, де факто, у нас 1 система и 0 связей. С минимизацией связей все отлично 🙂 Но вот количество систем очень маленькое.
А теперь, кто-то проделал анализ кода, и четко выделил 2 подсистемы, определил интерфейсы, по которым ведется коммуникация. Это значит, что границы подсистем определены и схема стала следующей:
Здесь у нас: 3 системы и 2 связи между ними. Обратите внимание, что количество функционала осталось тем же самым – архитектура ни увеличивает, ни уменьшает функционал, это просто способ организовать код.
Какое различие можно разглядеть между этими двумя альтернативами? При рефакторинге в первом случае нам нужно “прочесать” 100% кода (весь зеленый квадрат), чтобы убедиться, что мы не внесли никакой регрессии. При том же самом рефакторинге во втором случае, нам сначала нужно определить, к какой системе он относится. И потом весь наш рефакторинг сведется к прочесыванию лишь одной из 3х систем. Задача упростилась во втором случае! За счет успешного дробления архитектурой, нам достаточно сконцентрироваться лишь на части кода, а не на всех 100% кода.
На этом примере видно, почему дробить на максимальное количество объектов выгодно. Но существует еще и вторая часть цитаты – минимизация связей между ними. А что, если новая доработка, которая пришла к нам от начальства затрагивает сам интерфейс (красненький мост между 2мя системами)? Тогда дела плохи – изменения в интерфейсе подразумевают изменения по оба конца этого моста. И как раз чем меньше у нас связей между системами, тем меньше вероятность того, что наш рефакторинг вообще затронет какой-либо интерфейс. А чем проще каждый из интерфейсов, тем проще будет внести необходимые изменения по обе стороны интерфейса.
Интерфейс в самом широком смысле
Ключом к правильному применению архитектуры я считаю именно интерфейс, ведь он определяет формат взаимодействия и, соответственно, границы каждой из систем. Другими словами, от выбраных интерфейсов зависит и количество подсистем и их связанность (количество связей). Рассмотрим его поближе.
Прежде всего, он должен быть честным. Не должно быть коммуникаций между системами за пределами интерфейса. Иначе мы скатимся к исходному варианту – диффузия (да, она в программировании тоже есть!) объединит 2 системы обратно в одну общую систему.
Интерфейс должен быть полным. Актер по одну из сторон интерфейса не должен иметь никакого понятия о внутреннем устройстве актера по другую сторону моста – не больше чем то, что подразумевает интерфейс, по которому они взаимодействуют, т.е. интерфейс должен полным (достаточным для наших нужд) образом описывать партнера по “ту сторону моста”. Делая интерфейс полным изначально, мы значительно уменьшаем шансы того, что в будущем придется править интерфейс – вспомните, внесение изменений в интерфейс – это самая дорогая операция, т.к. она подразумевает изменения в более, чем одной подсистеме.
Интерфейс не обязательно должен быть задекларированным как интерфейс из ООП. Я считаю, что достаточно честности, полноты интерфейса и вашего ясного понимания этого интерфейса. Более того, интерфейс такой, как я его подразумеваю в рамках этой статьи – это нечто шире чем интерфейс из ООП. Важна не форма, а суть.
Здесь будет уместным упомянуть архитектуру микросервисов. Границы между каждым из сервисов – это ни что иное, как интерфейс, о котором я повествую в этой статье.
В качестве примера я хочу привести счетчик использования файла в inode на *nix (file reference count): есть интерфейс – если ты используешь файл, то увеличь его счетчик на 1. Когда закончил им пользоваться, уменьши его счетчик на 1. Когда счетчик равняется нулю, значит этим файлом уже никто не пользуется, и его нужно удалить. Такой интерфейс неописуемо гибкий, т.к. он не накладывает абсолютно никаких ограничений на внутреннее устройство актера, который им может пользоваться. В этот интерфейс органично вписывается как использование файлов в рамках файловой системы, так и файл декскриптор из исполняемых программ.
Решайте задачу на абстрактном, а не конкретном уровне
Очевидно, что умение выбрать правильный интерфейс – очень важный навык. Мой опыт мне подсказывает, что очень часто удачный интерфейс приходит в голову, когда ты пытаешься решить задачу на абстрактном (общем) уровне, а не текущем (конкретном) ее проявлении. Альберт Эйнштейн однажды сказал, что правильная постановка задачи важнее, чем ее решение. В этом свете я с ним полностью согласен.
Какое решение задачи “открыть входную дверь” вам кажется более правильным?
Смотря на проблему с абстрактной точки зрения, нам в голову естественным образом приходят полные интерфейсы. Ведь решая частное проявление проблемы, максимум, что мы можем придумать в плане интерфейса – это всего лишь его частная проекция на нашу частную проблему. Смотря на абстрактную проблему у нас больше шансов увидеть полный интерфейс, а не его проявление под какую-то конкретику.
В какой-то момент вы начинаете видеть эти абстрактные операции за их конкретными проявлениями (реализациями). Это уже отлично! Но не забывайте, что вам нужно минимизировать количество связей – это значит, что существует риск забраться слишком далеко в дебри абстракции. Абсолютно необязательно включать в вашу архитектуру все абстракции, которые вы видите при анализе. Включайте только те, которые оправдывают свое присутствие за счет дополнительной вносимой гибкости либо за счет дробления чрезмерно сложной системы на подсистемы.
Физика
Есть такая наука, и я ее люблю наравне с программированием. В физике многие явления можно рассматривать на разных уровнях абстракции. Столкновение двух объектов можно рассматривать как динамику Ньютона, а можно рассматривать как квантовую механику. Давление воздуха в воздушном шарике можно рассматривать как микро- и макро-термодинамику. Наверное, физики пришли к такой модели не зря.
Дело в том, что использование разных уровней детализации в архитектуре кода тоже очень выгодно. Любую подсистему можно рекурсивно дробить дальше на под-подсистемы. Подсистема станет выступать системой, и мы будем в ней искать подсистемы. Это divide and conquer (разделяй и властвуй) подход. Таким образом программу любой сложности можно объяснить на удобном собеседнику уровне детализации за 5 минут за кружкой пива другу программисту или начальнику нетехнарю на корпоративном собрании.
Как пример, что происходит в нашем ноутбуке, когда мы включаем фильм? Все можно рассматривать на уровне медиапроигрывателя (читаем содержимое фильма, декодируем в видео, показываем на мониторе). Можно рассматривать на уровне операционной системы (читаем с блочного устройства, копируем в нужные страницы памяти, “просыпаем” процесс плеера и запускаем его на одном из ядер), а можно же и на уровне драйвера диска (соптимизировать i/o очередь на устройство, прокрутить до нужного сектора, считать данные). Кстати, в случае SSD диска последний список шагов был бы другим – и в этом вся прелесть, т.к. в операционных системах есть интерфейс блочного устройства хранения данных, мы можем вытыкнуть магнитный диск, втыкнуть флешку и не заметим особой разницы. Более того, интерфейс блочного устройства был придуман задолго до появления CD дисков, флешек и многих других современных носителей информации – что это как не пример успешного абстрактного интерфейса, который прожил и остался актуальным на протяжении ни одного поколения устройств? Конечно, кто-то может возразить, что процесс был обратным – новые устройства вынужденно адаптировались под уже существующий интерфейс. Но если бы интерфейс блочного устройства был откровенно плохим и неудобным, он бы не выстоял на рынке и был бы поглощен какой-то другой альтернативой.
Человеческий мозг не может удерживать в голове много концепций/объектов одновременно, вне зависимости от того, говорим ли мы о физике или о программировании либо еще о чем-либо. Соответственно, старайтесь организовать вертикальную иерархию вашей архитектуры так, чтобы у вас было не больше дюжины актеров на любом уровне абстракции. Сравните два описания одной и той же системы:
Мы здесь обрабатываем входящие заказы. Сначала идет процесс валидации – проверяем наличие заказанных товаров на складе, проверяем правильность адреса доставки, успешность платежа. Потом запускается процесс уведомления – оператору приходит смс-ка с информацией о новом заказе. Начальник отдела получает имейл со сводной информацией.
Мы здесь обрабатываем входящие заказы. Сначала отрабатывает система валидации – проверяем точность и правильность всех данных. Ну в принципе, если тебе интересно, у нас там есть внутренняя валидация (наличие на складе и тп.) и внешняя (правильность информации, указанной в заказе). При успешной отработке валидации запускается система уведомлений – вот по этой ссылке найдешь полную информацию об уведомлениях.
Чувствуете, вертикальную ориентацию второго описания по сравнению с первым? Дополнительно, второе описание ярче выделяет абстракции “валидация” и “уведомление”, чем первое.
Как люди обычно летают на Луну?
Правильно! Они сначала проектируют ракету (ракету, как единое целое, и отдельно каждую из ее компонент). Затем они строят завод по производству каждой из компонент и завод по финальной сборке ракеты из произведенных компонент. А потом они летят на луну на собранной ракете. Чувствуется какая-то параллель?
На выходе получается огромное количество компонент, которые можно переиспользовать в других смежных целях. А еще есть заводы, которые эти компоненты массово производят. И успех всего предприятия в наибольшей степени зависит от успешной проектировки (когда в проект забыли внести модуль по регенерации кислорода, а ракета уже стоит на стартовой площадке – дела плохи), чуть меньше от качества построенных заводов (заводы еще можно как-то калибровать и тестировать) и меньше всего от конкретного экземпляра ракеты, которая стоит на пусковой установке – если с ней что-то случится, ее будет легко пересоздать на базе уже имеющейся инфраструктуры. Скоро научимся клонировать людей, и тогда даже при неудачных пусках о человеческих потерях не будет речи 🙂
В программировании все точно так же. На плечи железа выпадает роль заводов – исполнять наш код. Но вот роль проектировки (создания архитектуры) и конкретных имплементаций (постройка заводов) ложится на плечи программиста. Очень редко эти 2 этапа как-то явно выделяются из общего клубка. А мыслить об этих 2-х этапах раздельно очень полезно, более того, в других областях это даже выглядит нелогично. Ведь кто будет сразу строить завод, предварительно не решив, что же этот завод будет производить?
Преимущества архитектуры
Я здесь только резюмирую концепции, которые пытался описать выше. При успешном использовании архитектуры, мы имеем:
Признаки успешной архитектуры
Успешность архитектуры невозможно оценить однозначно “да” либо “нет”. Более того, одна и та же архитектура может быть успешной в рамках одного проекта (спецификации) и провальной в рамках другого проекта, даже если оба проекта номинально оперируют в одной и той же предметной области. В момент проектирования от вас требуется максимально глубокое и исчерпывающее понимание процесса, который вы автоматизируете/моделируете кодом.
Тем не менее, некоторые общие черты успешных архитектур я вам осмелюсь предложить:
Советы для построения успешной архитектуры
Попытайтесь задать 3 вопроса, когда анализируете задачу на архитектуру: Что мы делаем? Зачем мы это делаем? Как мы это делаем? За “что?” отвечает интерфейс, к примеру “мы уведомляем пользователя о событии”. За “зачем?” отвечает потребитель – код, который вызывает подсистему, и на вопрос “как” отвечает конкретная реализация интерфейса (поставщик услуги).
Постарайтесь любую самодостаточную операцию оформить в виде подпрограммы (функции, метода либо еще чего-то в зависимости от доступного вам инструментария). Даже если это всего лишь одна строчка кода, и используется она один раз в вашей программе. Так вы отделяете архитектурный код (список абстрактный действий) от имплементаций. В таком контексте эта функция выступает в роли интерфейса, и тут же получаем потребителя (вызывает функцию) и поставщика (реализация функции). Пример:
Ваше воображение работает в разы быстрее, чем ваши пальцы – валидируйте и “примеряйте” архитектуру на бумажке, прежде чем начать ее реализовывать в коде. Будет обидно понять через 5 часов кодирования, что придуманные вами интерфейсы не покрывают нужды предметной области, и эту проблему вы могли бы предвидеть, потратив 20 минут на анализ архитектуры и “проверку” архитектуры на бумаге. В некоторые моменты я провожу полный рабочий день сидя и смотря в небо – придумывая и обкатывая архитектуру на бумаге.
Не перегружайте ваши интерфейсы. В погоне за полнотой интерфейса, мы можем включить в него избыточные элементы, но здесь можно ненароком кашу испортить маслом. Чем больше элементов включает интерфейс, тем меньше свободы он оставляет тому, кто его будет реализовывать. Так же не забывайте, что возможно, в какой-то момент вам нужно будет изменить этот интерфейс в свете каких-то новых бизнес задач. Чем интерфейс проще, тем проще изменять его и актеров по обе стороны этого интерфейса.
Может звучать парадоксально, но перегруженный интерфейс будет менее полным чем идеально сбалансированный по нагрузке интерфейс. Излишние подробности сужают интерфейс, а не расширяют его, т.к. некоторые подробности теряют свой физический смысл в каком-то другом контексте. К примеру, мы могли бы “перестараться” и в наш интерфейс системы уведомления пользователя о каком-либо событии ввести понятие часового пояса: “уведомить пользователя о событии с учетом (или без) его часового пояса”. В некотором контексте это будет правильным интерфейсом, а в каком-то неправильным. Допустим пользователи нашей системы начнут жить на луне и там нет понятия “часового пояса” в таком смысле, в котором к нему привыкли земляне. Тогда это дополнительная нагрузка в интерфейсе окажется избыточной и будет действовать в ущерб всей архитектуре.
Не забывайте о вопросах производительности и масштабируемости в момент проектирования архитектуры. В идеале интерфейсы должны быть максимально простыми – допустим пару функций, которые позволяют изменять и удалять какую-то сущность из хранилища. Упаковывая в интерфейс лишь 2 функции мы получаем высокий уровень абстракции – мы можем использовать реляционную БД и NoSQL для физического хранения данных. Но если таких сущностей будут тысячи, то становится очевидным, что ими нужно манипулировать на уровне СУБД, а не приложения. Тогда нужно сознательно включить в интерфейс структуру БД, где эти сущности хранятся. В противном случае интерфейс будет красивым, но неполным, ибо с учетом требований производительности, полный интерфейс должен предоставлять быстрый и эффективный инструментарий для массового взаимодействия с сущностями.
Творение архитектуры
Способность правильно понять предметную область, идентифицировать успешные интерфейсы я отношу к искусству. В моем личном случае, я учился этому ремеслу через практику и созерцание архитектур других авторов, всегда пропуская исследуемую архитектуру через призму собственного критического мышления.
В следующий раз, когда вам нужно решить относительно большую задачу, отойдите от компьютера и посидите с листком бумаги час. В начале, возможно, никакие мысли не будут лезть в голову, но вы честно продолжайте размышлять над проблемой и абстракциями/интерфейсами, которые могут быть спрятаны внутри этой проблемы. Не отвлекайтесь – очень важна глубина погружения и концентрация, чтобы вы смогли максимально детально продумать и скомпоновать всех актеров и их связи у себя в воображении.
Когда вы видите чужую (либо свою, но какое-то время ранее реализованную) архитектуру, и вам нужно внести правки в код, попытайтесь проанализировать, удобно ли вносить эти правки при текщей архитектуре, достаточно ли она гибка. Что в ней можно улучшить?