Support us

Во что обойдётся выбор C++ для проекта?

Оставить комментарий
Во что обойдётся выбор C++ для проекта?

Выбирая технологию для реализации того или иного продукта, многие часто приравнивают стоимость разработки проектов на С++ к таковым на Java или C#, сравнивая системные программы с веб-разработками. Матёрые команды, проведя на продуктовом или офшорном рынке по 10 лет, накопив хороший опыт и заработав репутацию с Java и.Net в прикладной и веб-сфере, оценивают проекты С++ по «стандартной» схеме, пытаясь применить те же этапы к системным или кроссплатформенным проектам. И когда результат не оправдывает ожидания, это оказывается неожиданным сюрпризом для руководителей и владельцев бизнеса.

Читать далее

Иллюстрация: keepcalm-o-matic.co.uk.

Начну с небольшого описания специфики своей работы. Программирую с 1998 года, кроссплатформенность. Впервые руководить командой разработчиков мне довелось в 2003-м. Проекты, с которыми сталкивался впоследствии, — это достаточно большие системы, разработка которых ведётся по 5-10 лет, а количество кода могло достигать сотни мегабайт. Будучи задействованным максимально плотно в таких процессах, мне приходилось работать напрямую с владельцем и заказчиками. И круг проблем, с которыми сталкиваешься, часто выходит далеко за технические рамки

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

Три больших или пять маленьких?

Хочется особо отметить работу с «большими» проектами на С++. Безусловно, размеры проектов в WEB и.Net не меньше. Они развиваются куда интенсивнее и за более короткий срок существования разрослись до необъятных размеров. Но есть существенное различие. Каким бы веб-проект не был большим, у него всегда есть единица функциональности — веб-страница. Она не может быть бесконечно большой или сложной, она всегда ограничена набором статей и ссылок. Её легко можно показать или описать, что серьезно упрощает коммуникации с клиентами. Их можно кодировать шаблонами или по-отдельности, их можно реализовывать парралельно десятком программистов или последовательно одним — часто они связаны между собой только базой данных, а реализация специфичных функций будет находится где-то под обертками в бэкенде. На языках, хорошо адаптированных под веб (C#/Java/PHP), не пишут сетевые протоколы или движки к базам данных, не создают серверов или новые языки, не кодят драйверы.

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

  • серверно-подобные сервисы и бэкенды с сетевыми протоколами;
  • системы проектирования или дизайна (графические редакторы, САПР-ы и тд);
  • редакторы (тексты, диаграммы, данные), офисные программы;
  • десктопные программы с GUI и удалённым взаимодействием;
  • 3-D игры.

Каждая их этих видов программ требует уникального опыта по созданию того каркаса, в котором будет крутиться доменная логика. Поэтому иногда бывает довольно непросто объяснисть заказчику или менеджеру, что в реализации «средней программы» на С++ необхоим стек из десятка сторонних библиотек, где возникают экзотические проблемы на совместимость, распространяемость, версионность. Программа может использовать XML/JSON, пулы потоков, форматы данных, особенно графических, лицензионность и криптование с упаковкой, чтение и запись дополнительных форматов данных, подключение баз данных и работу с документами. В С++ ничего из вышеперечисленного нет в отличие от JAVA и С#.

STL? Дайте две!

Сравним стандарную библиотеку С++ (STL) с поставляемыми библиотеками в Java или C#. Оба языка (Java и C#) выпускаются в виде платформ, где разработчик может за вызовом пары тройки функций создать базу данных, открыть поток данных, используя хорошо зарекомендовавшие себя интерфейсы а-ля datasource, увязать это с файлом да ещё и распарсить его (xml или json например), расшифровать/зашифровать файл или буфер на лету, вывести это в графическое окно с хорошо устоявшимся GUI API. Там десятки библиотек, поставляемых с языком, в которых решены нюансы с типами, исключениями, базовыми классами. И самое главное, это всё уже взаимодействует с run-time фрэймворком, где решены все нюансы по работе с сообщениями, синхронизацией, GUI.

В С++ так просто этого не найдёшь. Каждый пункт в программе — небольшая база данных, синхронизация, файловая система, GUI, вывод графики, строки, контейнеры — это некая библиотека со своей историей развития и версионностью. Порой эти версии или библиотеки не совместимы. Так, например, в boost существует специфичный код для «правильной» работы с stlport. В stlport есть код для мирного сосуществования с boost. А преемственность версий в библиотеке ATL не сохранена. Перечислять можно долго.

Я архитектор

Иногда сам язык становится очень неоднозначным при дизайне библиотек и программ, с ним приходиться быть чрезвычайно осторожным. Всем извесны проблемы глобальных конструкторов, исключений в деструкторах, абстактные базовые классы с использованием шаблонов в модулях (.dll/.so) — это тема для отдельной статьи. И обсуждения таких пунков с разработчиками могут вылится в недопонимание. Зачастую разработчик увлекается базовыми классами, перегруженными функционалом, да ещё и с шаблонами, да еще и с бустом, да ещё и со встроенной многопоточнотью, да ещё с инфраструктурными елементами типа Cleanable, Destructable, и так далее…

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

  • Точно определить его функциональность и быть готовым декомпозировать её дальше.
  • Просмотреть, как это происходит в библиотеках типа буст, ACE, stlport и просто глянуть одним глазком, что думает об этом Google. Знать WinAPI, posix API.
  • Очень полезно знать, как называются классы в Java и/или C#. Эти платформы получили всеобъемлющее развитие и могут содержать гораздо более точные ключевые слова и более элегантные базовые классы.
  • Нужно правильно отделять инфраструктурную функциональность от предметной и системной и правильно подходить к операциям выделения памяти. Не смешивать всё в кучу, но и не забывать об этом.

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

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

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

А при чём тут перфоманс?

Одна из основных проблем C++  — это разобщённость. У Java существует единый репозиторий, где высококвалифицированная команда дорабатывает язык и сопутствующие библиотеки. И самое главное, они интегрируют его всюду, в том числе в мобильные ОС. С C# ситуация похожа — язык и инфраструктура развиваются как с академической точки зрения, так и с рыночной. С С++ не всё так однозначно. Так в boost-сообществе стремятся к некой академичности, упуская из виду практичность и доступность. Бьёрн Страуструп (Автор языка программирования C++. — dev.by.) прямо высказывается о необходимости упрощения библиотеки:

It is too hard to download and use just one Boost library;

the libraries seem overly coupled making it hard to pick and choose. Some of the libraries are too clever for my taste. Sometimes, generality and simplicity coincide; in Boost, the balance is IMO too often so far towards generality that novices and average users are lost.

С выходом нового стандарта и расширения языковых возможностей многие механизмы из boost просто утратят свою актуальность.

Другая проблема С++ — это высокая сложность. Так, Google во вступлении к Style Guide обосновывает многие пункты рыночной необходимостью упрощения кода. Они не только описывают декорацию использования языка, но упраздняют ряд ключевых возможностей (исключения, массивная инициализация в конструкторах), а так же минимизируют использование шаблонов и boost.

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

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

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

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

Специфика использования языка и библиотек может быть настолько разной, что имея, скажем, десятилетний опыт программирования под Windows, переход на специфику работы с Linux или того более с embedded может стать неожиданным сюрпризом. И просто потому, что встраиваемые системы требуют некоторого перфекционизма и увлечённости. Работа с десктоп-приложением может быть связана со звонками, хаотичными клиентскими пожеланиями, частыми релизами, что отражается на коде как хаки, лики и спонтанное съедание памяти, которая накапливается неделями, не освобождаясь — и это прокатывет в продакшене. Разработка бэкендов часто требует продумывания непростого дизайна до мелочей и изучения сторонних разработок, для чего нужна тишина и сосредоточенность. Совместить таких людей в работе бывает непросто.

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

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

  • MFC
  • ATL/COM/OLE/ActiveX
  • Qt
  • GTK
  • плагины для Crome/FireFox/Internet Explorer.

Причём плагины для разных браузеров нельзя поставить в один пункт из-за существенной разницы в API. Сложность работы с GUI в С++ в основном связана с несовместимым ядром для каждой библиотеки. Qt претендует на среду разработки и предлагает свой фреймворк, не позволяя иногда прозрачно встроить сервисоподобные модули с параллельной обработкой, использующих свой внутренний цикл сообщений. MFC полностью опирается на низкоуровневой WIN32, где приходиться думать и кодировать втройне. Поэтому некоторые программы на С++ имеют GUI в виде отдельного процесса, в котором приходиться определять полноценный сетевой протокол взаимодействия с сервисом либо привлекать на помощь COM. Оба подхода загромождают само решение, COM делает его Windows-зависимым, и оба метода значительно повышают стоимость разработки по сравнению со встроенным GUI.

Как иногда приятно бывает набросать скрипты на Java или C# и тут же выполнить их, не задумываясь о том, где и как установлен интерпретатор. Встраивание скриптовых возможностей в С++ модули — довольно витиеватая задача и тема для отдельной статьи.

Хорошо, что в веб-направлении CGI-модули постепенно заменяюся на более высокоуровневые PHP/Python/VB либо.Net. Помню, как в 2001 опально-скандальная Cronaintsep (минский офис провайдера addr.com) никак не могла разобраться, почему джависты строчат свои сервисы за считаные дни, а сишники копаются неделями и даже месяцами.

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

Сколько человек стоит ввести в проект?

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

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

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

Так есть ли способ писать программы на С++ дёшево?

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

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

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

Привлечение и использование базовых библиотек для проекта должно быть продуманным, ведь часто приходиться импелентировать то, что есть в «базе» с Java и C#. Диалог по передаче знаний — это процесс, где участники должны быть заинтересованы и должны уметь договариваться.

За 20 лет интенсивного развития индустрия накопила огромный опыт и знания, поэтому программист, вероятно, кодирует только 20% своего времени, остальная работа — это освоение, изучение, генерация и обсуждение, сравнение и принятие решений.

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

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

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


 

*Мнение колумнистов может не совпадать с позицией редакции.

Присоединяйтесь к сообществу dev.by

Читать

Читайте также
Аналитика и стратегия: курсы по бизнес-анализу для новичков и профессионалов (июнь, 2023)
Аналитика и стратегия: курсы по бизнес-анализу для новичков и профессионалов (июнь, 2023)
Аналитика и стратегия: курсы по бизнес-анализу для новичков и профессионалов (июнь, 2023)
Профессия бизнес-аналитика — один из самых быстрых и привлекательных способов «войти в IT». В среднем, бизнес-аналитик зарабатывает около $1500, а найти открытые вакансии для специалистов без опыта работы все еще реально.  На основе материала Digitaldefynd составили список курсов по бизнес-анализу, которые подойдут и новичкам, и экспертам. Это тренинги, сертификации и полноценные программы переподготовки. Как платные, так и в открытом доступе. 
10 курсов по C++ (июнь 2023)
10 курсов по C++ (июнь 2023)
10 курсов по C++ (июнь 2023)
С++, несмотря на свой солидный возраст, остается одним из основных языков программирования, который применется очень широко: от разработки ПО до создания игр. В сети много ресурсов, которые помогут освоить этот язык. Советуем обратить внимаение на подборку команды Digitaldefynd, котрую мы дополнили. В ней как платные, так и бесплатные ресурсы для людей с разным уровнем подготовки и знаний С++.
1 комментарий
10 курсов по SQL для лучшего понимания работы с большими данными (май, 2023)
10 курсов по SQL для лучшего понимания работы с большими данными (май, 2023)
10 курсов по SQL для лучшего понимания работы с большими данными (май, 2023)
Собрали 10 платных и бесплатных онлайн-курсов для изучения SQL. Программы рассчитаны на слушателей, которые только начинают или продолжают знакомство с языком.
10 способов научиться программировать самостоятельно
10 способов научиться программировать самостоятельно
10 способов научиться программировать самостоятельно
Хотите научиться кодить и освоить алгоритмы? Собрали десять советов с чего начать изучение программирования для тех, кто только начинает своё путешествие в мир программирования и снабдили все это полезными ссылками на курсы для начинающих программистов.

Хотите сообщить важную новость? Пишите в Telegram-бот

Главные события и полезные ссылки в нашем Telegram-канале

Обсуждение
Комментируйте без ограничений

Релоцировались? Теперь вы можете комментировать без верификации аккаунта.

Комментариев пока нет.