Философия программирования 6 — Продукт и Проект
Разница между продуктом и проектом в том, что при разработке продукта есть план, а при разработке проекта есть исследования. Если у вас есть какая-то не решённая проблема, скажем вы ещё не решили какую базу данных использовать в своём проекте, то вам понадобится этот вопрос изучать, то есть исследовать. Это называется technology research. Исследование, это вовсе не обязательно, что-то совершенно новое в мировом масштабе, если вы строите мост, то вам надо исследовать грунт в данном конкретном месте, и пока этот грунт не исследован, мост, как продукт, ещё не существует, пока что это — проект. Ещё не известно, какой грунт, а значит не известно из чего делать мост, как его укреплять, невозможно посчитать бюджет и распланировать график работ.
Конечно, любой проект похож на план, там есть последовательность действий, могут выставлять даже какие-то сроки, но пока в нём есть неисследованные белые пятна, это план с дырками, то есть — проект.
Если вы смогли разработать продукт и в процессе исследовать многие технологии, то вы получаете конкурентное преимущество на рынке, поэтому желание ввязаться не в разработку продукта, а в проект, это как болезнь такая. Программист думает: сейчас, мы тут вот это штучку исследуем, изобретём, и всех порвём. А любое исследование имеет неопределённый срок, и если вы себе, или вам программист говорит «надо ещё придумать как это сделать», сразу себе отмечайте: тут речь об исследованиях, то есть не о продукте, а о проекте. Проект имеет неопределённые временные рамки, обусловленные именно исследованиями.
При проекте свойственно мышление в духе: долго исследуем супер-фичу, мега-технологию, а потом быстро всё собираем и получаем продукт. Яркое отличие продукта в том, что в нём стадия «всё собираем» начинается очень рано, чуть ли не сразу, и большая часть графика отводится на доводку до ума всех частей. В проекте, наоборот, эта стадия наступает намного ближе к концу графика. График проекта похож на забивание десять тысяч гвоздей, можно сразу прикинуть как долго это займёт, и методично вколачивать. Вообще в проекте возникает ощущение, что «мы это уже делали, надо просто сделать ещё раз для данного конкретного продукта». Более того, процесс можно повторить по тому же графику создав ещё один схожий продукт. Многие успешные проекты, удались именно потому, что человек уже видевший весь график от начала до конца, уходит из коллектива и клонирует весь организационный проект, график работ и просто делает всё то же самое только качественнее, сознательно избегая исследований и экспериментов.
Если, скажем, у вас поле ввода иногда внезапно теряет фокус или неверно его перемещает, то с точки зрения проекта, это несущественная деталь, а с точки зрения продукта, это недостаток, который серьёзно может испортить его репутацию. Или там две кнопки однотипных на форме, но одна десятым кеглём, а другая одинадцатым. Мелочь, устраняется за 10 минут, надо найти нужный файл, нужное место, исправить, проверить. Никаких супер-технологий, но как минимум 10 минут долой. И в продукте таких мелочей обычно сотни и тысячи, они мелкие, их много и это позволяет применить главное оружие разработчика продукта — составить график. Сегодня исправляем тридцать косяков, завтра, и так сто дней, со всеми известными коэффицентами получим две тысячи рюшечек и деталей. А в проекте на это не останется времени.
Если бы я хотел сказать, что проект это плохо, а продукт — хорошо, я бы так и сказал. Я просто хочу чётко разделить эти два понятия, это, мне кажется, может сэкономить много усилий. Проект, само по себе это явление прекрасное, исследования тоже настоящее творчество. Более того, проект можно вести осознавая всю вероятностную и игровую суть исследований, мудро распределяя и проектируя даже эти неопределённые сроки. В конце-концов, это просто неопределённая проекция, но просто надо чётко осознавать чем именно ты занимаешься. Я лично, по опыту, привык все исследования вести до начала планирования продукта, все используемые технологии, принципы и правила, должны быть исследованы, вопросов не должно остаться, должно быть в конце исследований принято фундаментальное решение, что всё, берём эти решения, осознавая их достоинства и недостатки и переходим к стадии планирования, то есть разработки продукта.
Исследованиями являются и поиск подходящих технологий и инструментов, и создание уникальных алгоритмов и обучение персонала, и первоначальные исследования производительности, и составление списка нужных заказчику или рынку фич, и даже, поиск удобного рабочего режима. То есть всё, что заранее неизвестно и не может быть формально детерминировано. То есть к моменту начала разработки продукта, то есть составлению плана и графика работ, у вас уже не должно быть белых пятен, вопросов, и план составляется из твёрдых, осязаемых, весомых кирпичей. Как только у вас возникло чувство, что всё ясно, и надо просто работать, вколачивать гвозди или клонировать фишку из фишкой из продукта конкурента, то можно сказать продукт состоялся. Конечно, потом может оказаться, что он не будет успешен, и были совершены ошибки в планировании или в определении технического задания, или ошибки в собственно практической работе, но это уже будет учтено в следующем проекте/продукте.
Возможность накапливать опыт и переносить алгоритм работы из продукта в продукт, из проекта в проект, вообще отличает человека вставшего на правильный путь в разработке. Я например уже давно знаю, что изменение шрифта в кнопке, это в среднем не менее десяти минут, раньше мне казалось, что это дело секунд. Типизирование кирпичиков графика, способность сортировать все задачки и подзадачки по сложности исполнения, времени исполнения, требуемой квалификации — основной навык планирования. Некоторые виды задачек, очень не сложные, но имеют особенность сильно утомлять память и потом требуется увеличенное время для перехода к следующим задачкам. Если вы менеджер целого офиса программеров или одиночка, в любом случае вам нужно постоянно смотреть на себя со стороны, и не только радоваться, что очередной шажок исполнен, и думать сразу о следующем, но надо постоянно осмыслять и даже вслух произносить и записывать, какая задачка была решена, как долго она решалась, как она типизируется, какой опыт можно извлечь для дальнейшего планирования.
В этом смысле менеджер разработки, который сам не программист и не может правильно оценивать колечки в цепочке разработки, это бедствие. Такой человек сразу проявляется и его надо гнать, обычно достаточно чтобы он несколько раз удивился, почему-же это заняло так много времени? Менеджеру программистов разрешено испытывать удивление только в случае неожиданно быстрого прохождения определённого отрезка дистанции. И то — не желательно. Ясное дело, что если у программиста всё в голове и ему не требуется глубокое переключение на момент новой строчки в плане, то он может сделать что-то практически мгновенно. То есть вы исправили кнопку в трёх разных местах, на всё ушло десять минут, но это произошло так быстро только потому, что это однотипная работа, и так случилось, что все три кнопки исправлялись подряд. Но если бы вам надо было исправить кнопку в одном месте кода, потому исправить глюк в протоколе, потом ещё кнопку, потом найти деление на ноль, и снова исправить ещё одну кнопку, то каждое кнопочное исправление могло занять по десять минут. Более того, можно учитывать не только процесс разработки на одном шаге и время переключения, но и приступы энтузиазма и упадки сил. Самый главный талант менеджера, будь то само-менеджер, или менеджер коллектива, это умение отследить, когда работа тормозится из за внезапно появившегося исследования. Обычно наморщеный лоб или желание отвлечься от работы хороший признак. Значит у разработчика, что то не складывается в голове, не удерживается в памяти, равномерное движение по пунктам плана затыкается. Тут то и нужно проявить опыт и глубокое понимание, и «разрулить» вопрос — либо осознать, что исследование неизбежно и внести жирный ряд неопределённого размера в табличку плана, и бросить все силы на решение, либо обойти вопрос, применив проверенное альтернативное решение. Если вы делаете продукт, ваша задача не «лучше работать», а наладить процесс до полной предсказуемости.
Любопытное бытовое сравнение, хотя надо понимать, что любое сравнение это только сравнение и может лишь иллюстрировать некий принцип, это готовка обеда. Когда вам надо себя покормить, вы можете очень быстро приготовить еду, и можете позволить себе эксперименты и исследования в процессе. Побольше посолить, поменьше, новую приправу попробовать, но если вам надо сделать праздничный ужин и покормить дорогих гостей, то ситуация в корне другая. Вроде затраты должны быть линейно масштабируемы, 5 гостей, значит предполагаемые затраты на праздничный ужин в пять раз больше чем на собственный обеденный перекус, но на самом-то деле, затраты будут отличаться на порядок, и по выбору ингридиентов, и по тщательности исполнения и сервировки, потраченному времени. Это проект и продукт. Никто не станет экспериментировать с праздничным борщом, а если и станет, то пожалеет. Гости то придут ровно в пять, то есть имеется дедлайн. Затраты на сервировку и деталировку, нарезание сыра тонкими ломтиками, размазывание варенья ровным слоем, это вещи которые в обычном бытовом обеде делаются в десятки раз проще чем в праздничном режиме. Таков продукт, это праздничный обед. Сложность исполнения праздничного обеда или ужина, компенсируется тем, что в нём всё детерминировано, каждая операция отлажена годами, в лучшем случае хозяйка решается на одно необычное блюдо, и оно отнимает массу времени и сил и сопровождается охами по принципу: «я раньше никогда не делала, решила попробовать, не судите строго», ищет конкурентное преимущество, так сказать. К тому же всё прекрасно масштабируется, потому-что большинство операций типовые и их могут делать все кто окажется на кухне.
Сейчас исполняется год, как я презентовал сообществу свой проект Деодар. Это изначально был типичный «Проект», количество исследований которые нужно было провести, чтобы взяться собственно за исполнение продукта, сразу мной было определено как огромное. Начнём с того, что отсутствие качественных рывков в интересных мне средствах разработки удручало меня годами, даже десятилетиями. Сколько раз, устанавливая новую версию любимого средства разработки, редактора, IDE, отладчика вы удивлялись, как много разработчики сделали, и как опять ничего не изменилось по сути? В проектах с открытым кодом, вообще основная тенденция избегать фундаментальных изменений, тотального рефакторинга, а вместо этого приделывать к машине, всё новые и новые ручки, озонаторы и каждый раз перекрашивать двери. В то время как здоровый процесс итераций версий, должен предусматривать фундаментальные изменения по всем направлениям время от времени. Одно из таких фундаментальных изменений это решение проблемы, которую на бытовом языке можно назвать «не хватает маленькой штучки». То есть имеется прекрасный инструмент, всё устаревает, но не хватает одной привычной, нужной именно вам, маленькой штучки и из за этого продукт разработанный с ресурсом сотни тысяч человеко-часов не устраивает, из за функционала, разработка которого занимает один человеко-день.
Разработчику, как человеку решающему нетривиальные задачи, очень важно опираться на инструмент, и зависимость от этого инструмента определяет принятие стратегических решений в планировании.
Сколько раз вы слышали фразу «мы решили отказаться от. »? Моя юность пришлась на расцвет продуктов Борланд в России, я учился профессионально программировать и использовал Турбо Паскаль и позднее Дельфи. В связи с чем, у меня выработались некоторые навыки работы, привычка опираться на такие инструменты среды как F4 (Run to cursor), Control+Enter (Open file at cursor), мгновенная компиляция. Для меня стало критично, чтобы одной кнопкой я мог откомпилировать, поставить останов под курсором и запустить программу, потом так же терминировать её одной кнопкой и продолжить редактирование кода. Когда я пытался работать в привычном мне режиме на Visual Studio меня кроме на порядки более медленной компиляции сильно сбивало необходимость запускать отладчик одной кнопкой, запускать программу другой, предварительно удалять предыдущий брейк-пойнт и ставить новый, это целый процесс, на который я уже не мог отвлекаться. За несколько дней я написал макрос который кое-как решал проблему. Конечно, это мои личные пристрастия, но проблема в том, что у каждого программиста есть свои личные пристрастия, без них не бывает программиста, даже маляр имеет свои личные пристрастия к методам и инструментам. Один мой знакомый станко-наладчик, не мог работать если у него не было под рукой ванны с бензином, в которой он мог бы мгновенно в любое время полностью вымыть руки до предобеденной чистоты. Он ужасно страдал, когда приходилось работать в другом цехе, где такой ванны не было. Мелочь, но из таких мелочей и складывается рабочий процесс.
Я всегда постулировал такую вещь, как совершенство средств разработки. Знаете, как производство средств производства у марксистов, которое отличает развитую экономику от просто механизированной. Моё убеждение, что верно усовершенствованное средство разработки может ускорить разработку не на проценты, а на порядки, и не только ускорить, но и дать возможность разработчику браться за задачи иной степени сложности. Лет пять назад я сделал амбициозную попытку создать соответствующую моим требованиям C++ IDE. Она называлась DaoIDE. Для этого мне пришлось решить несколько фундаментальных проблем. Во-первых сделать свой текстовый редактор или научиться эффективно использовать Scintilla или другой открытый аналог. Текстовые редакторы я делаю сколько себя помню. Вообще, создание текстового редактора, это образец сложной задачи по программированию. Всё видно на экране, и сложнейшая структурность, это идеальная задачка для продвинутых учеников. Моя любовь к текстовым редакторам расцвела когда мне приходилось работать с приложением Aldus Page Maker, я открыто восхищался тем, что может эта программа, и ведь её написали в конце 80-х, начале 90-х. Мне довелось написать десятки текстовых редакторов from scratch, то есть с нуля. И это не считая сотен быстрых прототипов. От простейших нотепадов для доса, до систем со сложным маркапом и спец-требованиями. Так что с редактором не было особых проблем. Потом пришлось разбираться с отладчиком, я сделал множество прототипов интеракции среды с отладчиком, на основе dbghelp.dll, на чистом ассемблере, через GDB, GDB-MI, WinDbg и разных готовых обвесов над ними. Меня в процессе ужасало — как это сложно, насколько плохо всё документировано, очевидно, что ни один отладчик изначально не делался для встраивания в сторонние приложения. Потом пришлось разбираться с компилятором С++, основное моё требование к нему была скорость компиляции. Мне пришлось детально разобраться в истории разработки существующих компиляторов и убедиться, что самый быстрый компилятор (именно в смысле скорости компиляции, а не в смысле скорости работы скомпилированной программы) это Digital Mars C++ (DMC), бывший Symantec C++. Моё рассуждение простое, в процессе разработки приложения, его надо запустить много тысяч раз, а оптимизированный исполняемый выход нужен только в момент релиза один раз. DMC часто отрабатывал в несколько десятков раз быстрее соперников, давая перформанс близкий к привычному реактивному компилятору Delphi. Но он не давал возможности дебажить эти экзешники, из за лицензированного десятилетия назад формата объектного файла. MSVC, особенно ранних, версий был в разы быстрее GNU C++. Но не было шансов на кросплатформенность и жуткая невнятная документация, каждый чих, типа определения типа переменной, приходилось исследовать сутками. Этот проект занял у меня не меньше года, почти всё время ушло на исследования.
Проект среды С++ Дао заглох именно потому, что я убедился в неприменимости всех существующих IDE-строительных блоков доступных в мире, в первую очередь компиляторы, дебаггеры. Решая эту задачу, я потратил кучу времени изучая не только исходники но и сообщество и историю разработки этих инструментов. Например, я понял, что GCC никогда не будет быстро компилировать, более того, он с каждой версией будет компилировать всё медленнее, таков запрос рынка и таков фокус разработки. Не говоря про то, что сам направляющий комитет работает очень специфично, и пересматривать фундаментально устройство компилятора не станет никогда. Логика проста, там всё и так сделано по науке: lexer, AST, backend, codegen и т. п., нечего тут изобретать. Когда я увидел первое видео с рассказами авторов LLVM/Clang я прыгал от радости, было очевидно, насколько более творчески и решительно мыслят Apple и Google. Устройство GDB тоже кошмар и исторически и технически. Тут я должен разъяснить, что если я констатирую ужасность этих проектов, но это не значит, что мне они не нравятся, или я считаю идиотами, тех кто их сделал. Вовсе нет, это проекты мировые, и MSVC в том числе, компиляторы С++ вещь настолько сложная, что их в мире единицы, и все кто над ними работают это супер-люди! Можно буквально перечислить по пальцам проекты такого уровня. Просто стало ясно, что люди работают в другом направлении, чем то, которое близко лично мне. И мы снова возвращаемся к идее о совершенстве средства разработки и личных навыков разработчика.
Просто таков мой стиль, мне важно чтобы процесс тёк, важно чувствовать мгновенную отдачу, и запускать приложение после каждого крохотного изменения, ощущать. Это не плохо и не хорошо, просто это мой персональный стиль. Кстати он не так уж эмпиричен по сути, есть и исследования у психологов. Например, доказано, что для успешной работы разума, для закрепления памяти человеку нужно мгновенно получать результат, это гласит теория обучения и плодотворной работы. Мы тут снова затрагиваем тему психологии, я уверен, что без глубокого изучения процессов памяти, принятия решения, настроения и прочего детального исследования программиста за работой, наше совершенствование средств разработки будет крайне неэффективным.
Отчасти это объясняется маркетинговым сознанием западных производителей, если есть рынок, люди пользуются средством разработки, то зачем его фундаментально менять? Это же основы маркетинга. Если человек привык курить махорку, то не надо пытаться продать ему сигары, не лишай себя рынка, лучше перемолоть сигары в махорку и продавать улучшенную махорку. Зачем совершенствовать компилятор в неожиданных направлениях, если есть огромная пользовательская база уже обученная опираться на то, что есть? Надо просто подпиливать, и подкрашивать. Сейчас даже есть маркетинговая стратегия направленая на еженедельные, например, апдейты, а то, что там опять только «забор перекрасили» или кнопочку передвинули, это мелочи, главное, что — «проект жифф». Так выходит, что обычно сколько нибудь новые смелые решения на рынке появляются с новым продуктом, а не с новой версией уже существующего. Такие радикальные изменения, которые принесли Руби и Питон невозможно было бы ожидать от новой версии любой существующей системы.
Когда я писал YaUI, где надо было использовать сразу четыре языка программирования и три разных платформы, и соответственно, никакой отдельно взятый отладчик не мог это всё покрыть, я уже полностью и привык и полюбил отладку без отладчика, через кодомодификацию. Более того, я перевёл всю разработку в обычный notepad++, с компиляцией в командной строке, через скрипты, в результате мне удалось добиться одинакового подхода к разработке на всех трёх платформах и четырёх языках. (Java, ObjC, C++, JavaScript, Android, Windows, iOS). Когда я понял, что можно кодить вообще без монструозных IDE, убрать зависимость от этих огромных тормозных миров, можно вообще не компилировать и использовать Node.js, и не ждать когда в отладчике опять исправят очередной недостаток, я понял, что хочу сделать минималистский инструмент для такого стиля программирования. Так, собственно, и родилась идея Деодара. Хотелось ещё отказаться и от Windows, и уменьшить зависимость от ещё одной корпорации, то есть источника непредсказуемых перемен. Тут собственно я и возвращаюсь к основной теме статьи — проект и продукт, потому что мне сразу стало ясно, что написать нечто такое можно только проведя очень длительные исследования. То есть я хочу на собственном примере показать, как я пытался сознательно провести длительные исследования перед, собственно, работой над продуктом.
Первая задача с которой я столкнулся и которую решал около полугода, осознавая, что я могу и не справиться, была работа с окнами, экраном и клавиатурой. У меня уже был опыт разработки под XWindow System, и когда я только решил в этом разобраться, я в очередной раз убедился, что вся документация для юниксов построена по принципу манов, то есть если ты знаешь что набрать, ты набираешь и тебе написано, как это сделать, но если ты не знаешь как называется функция которая делает то, что тебе надо, ты будешь идти очень долгим путём. В конце-концов я научился работать с экраном и окнами через сокет по XWindow Protocol просто читая старинную спецификацию. Но мне не удалось главного, отрисовать Anti Aliased Text. То что в Windows или на Маке делается вызовом одной функции, в мире иксов целая история. Мне пришлось создавать OpenGL контекст и ручками рендерить туда буквы используя FreeType или HarfBuzz. Проблема была в том, что никак не удавалось достичь нормальной скорости, FPS. Я исследовал несколько десятков альтернатив, всевозможные тулкиты и обёртки, начиная от общепринятых GDK, Qt, FLTK, SDL и до очень сложных гибридных решений, включая GLUT, Pango в разных комбинациях. И каждая такая попытка занимала дни и даже недели. Десятки папок с прототипами лежат до сих пор. В конце концов я разобрался во всём и решил использовать Xlib+FreeType+OpenGL textures.
Далее возникла проблема буфера обмена. Оказалось, что на чистом Xlib это целая история и у меня опять ушли недели на решение этой проблемы. Мне кажется, людей понимающих как работает клипборд в линуксе на уровне иксов в мире единицы. Опять невероятно трудноуловимая документация. В конце концов я создал демонстрационный hello world на эту тему и выложил на гитхаб, теперь любой может в двадцати строчках увидеть как это делается на С. Поразило, что на Стэковерфло люди не смогли ничего внятного сказать по вопросу. Потом возникла проблема юникодного ввода текста и опять дни и недели исследований, десятки чужих примеров, которые все как обычно не работали и наконец удалось разобраться и с этим. Кстати, рассматривался и вариант работы Деодара из под консоли. Но поймите, терминал это древняя технология, он до сих пор совместим с телетайпами шестидесятых годов. Это рудимент, и главная проблема терминала это невозможность отлавливать нажатия на клавиши, то есть элементарное onKeyDown, onKeyUp в принципе невозможно на терминале в сущности являющимся потоковом символьным устройством на прямую не связанным с hardware. Недавно автора BASH спросили, как он видит будущее своего детища. Знаете что он ответил? Хочу, говорит, чтобы BASH поскорее исчез и его все забыли и создали наконец что то более современное, соответствующее современным задачам.
Потом надо было исследовать вопрос, использовать ли чистый движок V8 или Node.js? Как такое решить? Пришлось написать оба варианта и выбрать лучший. Оказалось, что возможности Ноды совершено достаточны и возможность подключать npm модули это большой плюс в сторону этого решения. И только тогда стало возможно переходить к собственно работе над продуктом. Хотя ещё оставалось изобрести свой аналог Turbo Vision, что тоже оказалось весьма нетривиальным делом. Оказалось, что в JavaScript прототипное наследование не цепочное, то есть если вы пропустили в промежуточном потомке перекрытие метода, то он автоматически перекрывается как копия. Поясняю: у вас есть классы A->B->C и вы написали A.draw() и С.draw(), и из С.draw() вам надо вызвать А.draw() то вы никак не можете это сделать анонимно если ТОЧНО не знаете, был ли написан B.draw(). А для аналога Turbo Vision с его цепочным анонимным наследованием это было критическим вопросом. Анонимное это значит что вы не пишете A.draw.apply(this), а пишете this.inherited.draw(). Ведь B.draw() может существовать, а может и отсутствовать. Я перечитал всё, что было в интернете по вопросу наследования в JavaScript, оказалось, что это не так уж много, все в основном ссылаются на одни и те же две три работы, и в них эта проблема тоже не решена. Мне понадобилось ещё несколько недель, чтобы разобраться в самых тонких деталях наследования в JavaScript и понять как можно эту проблемку решить, в результате появился репозиторий dnaof на Гитхабе.
Собственно Деодар как продукт заключался в гибриде классического двухпанельного файлового менеджера с его реактивной слепой навигацией и очень удобного текстового редактора, не уступающего Notepad++, SublimeText и прочим, по интересующим меня параметрам. Ещё важнейшим моментом было внедрение терминала внутрь Деодара. То есть по нажатию Escape пользователь видит запущенный BASH и все три компонента, редактор, файловые панели и консоль очень плотно соединены в конгруэнтную систему. И главная киллер фича, конечно, это собственно JavaScript, то есть этой среде не нужны какие-то API для разработки плагинов, у вас весь исходный код под рукой, и он минималистичен, это не миллионы строк а считанные тысячи. К моменту прошлогоднего релиза, с даты которого прошёл ровно год, всё ещё оставались две не решённые фундаментальные проблемы. Не удалось достичь желаемой скорости отрисовки, то есть она была приемлема, но хотелось ещё больше FPS и не удалось понять, как попасть в репозиторий Ubuntu, хотя-бы. Поэтому Деодар пока остаётся проектом. Прорисовку мне недавно довелось переписать и выйти на желаемый показатель performance. Теперь вся эта эпопея продолжается, потому что я сразу осознавал, что это ПРОЕКТ и длится он будет годами и надо понимать, что каждый шаг включает исследования с открытой датой.
Собственно уровень продукта ещё впереди, для меня это вопрос интерфейса, ведь как говаривает Линус наш, Торвальдс — если в вашей программе есть фича, но её нет в интефейсе, то и ФИЧИ НЕТ. А в Деодаре до сих-пор нету даже менюшек, калкулятора, редактора палитры, работы с архивами и прочего. Кстати, работа с архивами вещь нужная, просто в работе именно программиста, она вторична, моя же цель была сделать не столько файловый менеджер как таковой, а рабочую среду программиста с файловым менеджером внутри. Но для продукта и это нужно.
Ну вот, надеюсь вам было интересно провести этот небольшой экскурс в философию программирования и небольшой пиар моего проекта. Ко мне тут неоднократно в комментариях обращались с претензией, что уже какая статья в серии Философия Программирования, а собственно о программировании пока ничего нет. Моя цель писать именно о программировании, осмысляя это явление всесторонне, а не только чисто технически. Ведь большинство текстов о программировании крайне однобоки, из серии «вот поставил новую версию Х, позвольте рассказать на какие грабли пришлось наступить». Опять же, я не ставлю оценок, что хорошо, а что плохо, такие тексты сами по себе хороши, решают свои задачи. Но нам необходимо подкапываться к более сложным вопросам, развивать язык, вводить новые понятия, расширять существующие. Вот сегодня я попытался взять заезженные казалось бы понятия Проект и Продукт и порассуждать, прилюдно, чем они отличаются. Ведь, то, что происходит у программиста в голове нуждается в умении высказать, а мы до сих пор только тычем пальцем в экран и мычим, «ну что ты не понимаешь» или «смотри в код», «ну что поделать если люди не умеют программировать». Может они умеют, просто ты не знаешь как объяснить то что думаешь об этом участке кода? Это же вопрос развития языка. Возьмём к примеру замыкания, ведь нет в языках программирования такого ключевого слова, а замыкание есть! То есть понятие вводится исключительно гуманитарно, в голову программистов, мол смотрите, вот как можно написать и получится «замыкание», с ним можно делать и то и это. Потом понятие развивается, добавляются дочерние понятия, расширяется набор ассоциаций. В общем будем работать, двигаться в выбранном направлении. Я очень надеюсь, что если двигаться целенаправленно, то рано или поздно удастся найти правильный тон рассуждения о предмете и сильно обогатить наше представление о профессии. И огромное спасибо всем кто принимает участие в комментариях, даже тем кто меня минусует, критикует, а особенно тем кто читает и ждёт продолжений!
Что такое продукт и проект в IT
Приветствую! За много лет работы на острие разработки продуктов и проектов в IT сфере я получил очень разносторонний опыт, и настало время начать им делиться. В этом блоге я буду рассказывать о различных аспектах, с которыми столкнется тот, кто решит разработать свой IT продукт или проект. Как и при создании продукта, для блога важно определить цель. Моя — помочь горящим своей идеей людям, только встающим на дорожку, ведущую через дебри IT-сферы, увидеть более полную картину происходящего, не допустить кучу ошибок, наладить эффективную работу и, в результате, достичь поставленных целей. Возможно, через несколько лет я буду счастливым пользователем продукта одного из моих читателей. Добро ведь возвращается?)
“Да кто ты такой?” — спросите вы. А я отвечу. Я — Дима Балашов, руководитель проектно-аналитического направления компании Decart IT-production, занимающейся заказной разработкой проектов и продуктов и предоставляющей аутстафф-услуги крупным российским компаниям. За более чем 6 лет работы я управлял разработкой проектов для России и ЕС, занимался продуктовой и бизнес-аналитикой. Все это позволило получить богатый опыт как в работе над продуктами вместе с их основателями, так и в организации работы команды разработки.
Кому же будет полезен блог?
- Стартаперам: как будущим, так и действующим.
- Собственникам малого бизнеса, которые хотят эффективно цифровизировать компанию.
- Ответственным за реализацию IT-проектов не в IT-компаниях.
- Тем, кто хочет начать карьеру в IT, и на данный момент выбирает направление деятельности
- Тем, кто уже работает в IT и хочет перейти на позицию продакт или проджект менеджера
На этом вводная часть закончена, переходим к делу!
В этом блоге я часто буду использовать термины продукт и проект, а также позиции продакта(product manager) и проджекта(project manager). Давайте разберемся, что это, в чем отличия и как они влияют на принятие решений.
Согласно американскому институту проектного менеджмента:
Продукт — произведенный артефакт, который можно выразить количественно и который может являться как конечным объектом, так и компонентом.
Проект — временное предприятие, направленное на создание уникального продукта, услуги или результата. Временный характер проектов определяет существование начала и конца работы проекта или ее фазы. Проекты могут существовать самостоятельно или в составе программы или портфеля.
Возьмем приложение Камера на iPhone. Это продукт, который является неотъемлемой частью другого продукта — самого iPhone. При этом разработка конкретной версии этого приложения является проектом, имеющим даты начала и завершения. Будет выходить следующая iOS, и в рамках продукта iPhone инициируют новый проект по улучшению приложения Камера.
Помимо временных двумя другими ограничениями проекта являются объем работ и стоимость.
В результате мы получаем треугольник, площадью которого является качество или, иными словами, результат работ. Данная визуализация наглядно показывает, как изменение одного параметра влияет на качество или, при необходимости сохранения качества, на один или оба других параметра.
Например, вы обратились за разработкой ИТ-проекта, который оценили в 2 млн, а у вас есть 1,8 млн. В таком случае вы можете:
- Уменьшить объем работ. Это можно сделать двумя способами или их комбинацией: убрать часть функционала или упростить имеющийся.
- Увеличить срок выполнения работ. На это могут идти не все компании-разработчики и не во всех ситуациях, но я в своей практике пару раз так делал. Для заказчика это плюс, если не горят сроки. Фактически чистая экономия денег. Для исполнителя это снижение рисков и возможность для уменьшения себестоимости разработки, в результате чего его чистая прибыль может не измениться или даже увеличиться.
- Осознанно “ухудшить” качество. Качество бывает внутреннее и внешнее. Внешнее — видимое пользователем. Проявляется в виде багов, непродуманных пользовательских сценариев и тд. Внутреннее — недосягаемое для пользователей. Проявляется в виде проблем в дальнейшем развитии сервиса(или даже невозможностью это сделать), увеличении стоимости разработки.
На практике, при необходимости изменения одного параметра, чаще всего изменяют два других угла треугольника, не трогая качество. Более подробно все эти пункты разберу с примерами в одной из следующих статей. Подписывайтесь, чтобы не пропустить
Подытоживая, проект делает упор на реализацию определенного функционала с определенным качеством в определенные сроки за определенную стоимость.
У коммерческого продукта совсем другой фокус. Я разделяю его на создание ценности для клиента и управление финансами.
Создание ценности включает в себя:
- Простоту получения продукта. Сколько времени и денег придется потратить, чтобы начать использовать продукт. Сюда можно отнести время на заключение договора или стоимость интеграции.
- Простоту использования продукта. Нужны ли специальные навыки для работы с продуктом, какого риски при работе с ним. И до Тинькофф Инвестиций можно было торговать акциями, но именно этот продукт вывел сферу на новый уровень простоты.
- Профит от использования продукта. Насколько эффективно продукт закрывает потребности пользователей. Например, после внедрения продукта А производительность сотрудников отдела В в среднем выросла в Х раз.
- Стоимость продукта. Сколько стоит и насколько он интересен пользователю с учетом этом стоимости.
- Ценность бренда. Уверен, вы легко назовете с десяток брендов, у которых стоимость бренда в общей стоимости их товаров или услуг значительно выше себестоимости.
Управление финансами содержит:
- Модель получения прибыли. Подписка, разовая оплата, оплата за количество и тд
- Стоимость продукта. Из чего она формируется, что на нее влияет
- Распределение доходов и расходов.
В итоге те, кто работают над созданием продукта, должны балансировать между ценностью продукта и его финансовыми показателями. И в этом вопросе нет единственно правильного ответа.
Последним различием, о котором хочу поговорить, является подход к работе. Разработка продуктов основана на тестировании гипотез. Что это значит? Вы не можете быть заранее уверены, что внедрение фичи А со стоимостью реализации В увеличит показатель Y в Х раз. Это просто невозможно на данном этапе развития людей и технологий. Поэтому команда строит ряд гипотез, оценивает их по нескольким параметрам и выбирает для реализации те, у которых оптимальное соотношение пользы и стоимости. Далее эта гипотеза тестируется. Если гипотеза подтвердилась или по крайней мере показала положительную динамику, она внедряется на постоянной основе. Если нет, анализируются причины, и делаются выводы.
Подробно расскажу обо всех этих процессах в следующих статьях.
Проектом в данном примере будет являться реализация фичи А. При этом у команды будет ряд ограничений в виде стоимости В, срока, к которому должна быть готова фича, и непосредственно требований к самой фиче. В рамках этих ограничений команда проекта должна предложить оптимальное решение по реализации. Успехом проекта будет реализация в соответствие со всеми требованиями.
Приходя в IT, вы точно столкнетесь с проектами. С продуктами — в зависимости от запроса. Но очень важно понимать различия между ними, и с чем вы работаете в данный момент. У проектов и продуктов разные цели, принципы работы, метрики и тд. Их понимание даст вам богатый инструментарий по достижению поставленных целей. Понять их и научиться применять я помогу вам в следующих статьях! А конкретно в следующей расскажу про продуктовую аналитику: первые шаги от идеи к продукту.
Как спланировать и создать собственный проект
Photo by Najla Cam on Unsplash
В этой статье я расскажу, как следует планировать свои проекты. Это поможет вам начать создавать потрясающие вещи, попутно повышая свои навыки программирования.
Эта статья не о том, как структурировать ваши папки или как настроить расширения VS Code, чтобы обеспечить чистоту кода при сборке. Моей целью было помочь начинающим программистам почувствовать себя более уверенно на пути из туториального ада, помочь им начать создавать свои собственные проекты.
Новичкам взяться за новый проект не так просто, как кажется. Когда вы не можете воспроизвести результаты только что просмотренного урока на YouTube, не пересмотрев его заново 30 раз, собственный проект представляется просто недостижимой вершиной.
Когда я только начинал учиться программировать, я брался за какой-нибудь курс или следовал туториалу и думал, что понимаю материал. Но как только я отрывался от источника и пытался воспроизвести проект самостоятельно, у меня ничего не получалось.
Чтобы преодолеть эту проблему, я написал о ней в популярном сабреддите r/learnprogramming. Все комментаторы советовали мне сосредоточиться на создании моих собственных проектов.
На первый взгляд этот совет кажется прекрасным и правильным. Но моя проблема заключалась в том, что я даже не мог просмотреть руководство и затем самостоятельно воспроизвести то, что там делалось. Где уж мне самому осилить проект? Это в десять раз сложнее, чем повторить то, что увидел в туториале. Мне казалось, что мне это вообще не по силам. Я понятия не имел, с чего хотя бы начать, не говоря уже о том, как собрать потом все это воедино.
По сути, проблема заключалась в том, что я не знал, как добраться из пункта А в пункт Б.
Я часто встречаю посты на эту же тему на r/learnprogramming. Начинающие вроде меня расстраиваются из-за того, что не могут выбраться из ада туториалов, и поэтому обращаются за советом. Но всем, как и мне, просто бросают совет заняться собственными проектами. Люди не задумываются над тем, что если новичок не может даже воспроизвести учебник, создать свой собственный проект для него будет реальной проблемой.
Пока учился программировать, я видел так много примеров одного и того же вопроса и одних и тех же ответов. И я подумал, что пришло время что-то с этим сделать и тем самым вернуть свой долг сообществу.
Итак, перед вами статья о том, как создавать свои собственные проекты, чтобы улучшить навыки разработчика и закрепить изученное.
Чтобы спланировать и создать программный проект, я делаю три ключевых шага.
Шаг 1. Определение проекта
Первым шагом при планировании личного проекта является его определение.
Определение проекта — это описание его на человеческом языке. Оно должен быть очень простым, чтобы любой, кто его читает, мог понять, в чем суть.
Определяя проект, я задаю себе четыре вопроса:
- Что собой представляет этот проект?
- Что собой представляет MVP (минимально жизнеспособный продукт)?
- Какая будет «посыпка»?
- Когда проект можно считать законченным?
Сначала пончик (MVP), посыпка — потом
Один из самых важных уроков, который мне преподали на курсах по программированию, заключался в том, что начинать надо с пончика, а не с посыпки.
Нас всегда тянет сделать что-то фантастическое, добавить потрясающие функции, которые произведут впечатление на потенциального работодателя. Но если ваше приложение не выполняет свою основную функцию, все изюминки пропадут даром. У вас просто не будет в руках пончика, который можно покрыть посыпкой.
Поэтому обязательно определите минимально жизнеспособный продукт, создав который, вы сможете заняться посыпкой.
Пример определения проекта
Возьмем простой пример. Допустим, мы собираемся создать приложение-калькулятор. Тогда наше базовое определение проекта будет следующим.
Проект «Калькулятор»
- Чтособой представляет этотпроект? «Калькулятор» — это проект по созданию калькулятора, доступного в браузере. Проект будет реализован с использованием HTML, CSS и JavaScript. Это позволит пользователям вводить числа и вычислять результаты выбранной ими арифметической операции.
- Чтособой представляетMVP? Минимальный жизнеспособный продукт — это калькулятор, который отображается в браузерах и может выполнять операции сложения, вычитания, умножения и деления на основе ввода пользователя и показывать пользователю результат вычислений.
- Какая будет «посыпка»? В этом проекте «посыпка» — это стилизация калькулятора. Также к «посыпке» относится возможность для пользователя нажимать цифры и арифметические знаки на клавиатуре, а не только кликать по кнопкам на экране. Еще можно добавить операции более высокого порядка, такие как возведение в степень.
- Когда проектможно считать законченным? Проект будет завершен после реализации всех функций MVP и оформления калькулятора.
Это определение простое и понятное. Если бы моя мама его прочла, она бы поняла, что это за проект. Здесь есть описание проекта, функционала MVP, необязательных функций, которые вы можно создать, а также указана «точка выхода» — описание завершенного проекта.
Определяя проект, вы делаете его менее устрашающим.
Когда у вас есть определение, можно приступить к следующему шагу.
Шаг 2. Создание рабочего процесса
Этот шаг самый простой. Обычно его можно объединить с шагом 3, но сейчас мы рассмотрим его отдельно. Проделав один раз, вы сделаете это шагом по умолчанию для всех ваших будущих проектов.
Для начала нужно использовать что-то вроде Trello — бесплатного инструмента для управления проектами.
Trello позволяет нам использовать метод управления разработкой Kanban. Новичку не обязательно знать или понимать, что собой представляет Kanban, вы можете просто использовать его практики.
Чтобы настроить нашу канбан-доску, создаем 4 столбца:
- TODO (нужно сделать)
- DOING (в процессе)
- DONE (сделано)
- BUGS / NOT SURE HOW TO DO (баги / не уверен, как это сделать)
В эти столбцы мы будем добавлять карточки. Мы создаем карточку в столбце TODO, затем, взявшись за выполнение, перемещаем ее в столбец DOING, а покончив с ней — в столбец DONE. Если вы столкнулись с какой-то ошибкой, на которой застряли, или не знаете, как что-то сделать, можно переместить карточку в столбец BUGS / NOT SURE HOW TO DO.
Этот рабочий процесс представляет собой суперупрощенную версию Kanban. Когда устроитесь работать в качестве разработчика, у вас, скорее всего, будет больше столбцов. Там добавятся столбцы для тестирования, код-ревью, бэклога и другие. Но для ваших собственных проектов, особенно если вы новичок, вполне хватит и четырех.
Теперь, когда у нас настроен рабочий процесс, мы можем перейти к последнему шагу, который больше всего меня озадачил, когда я учился программировать.
Шаг 3. Разбивка проекта на более мелкие компоненты
Ключ к созданию собственных проектов — разбиение большого проекта на более мелкие и менее пугающие компоненты. Эти компоненты становятся нашими карточками в Trello.
Звучит достаточно просто, но когда я только начинал, я и не догадывался, что так можно. Я думал, что большинство разработчиков просто начинают писать код, и проект буквально вытекает из-под их пальцев, как в кино. И, конечно, я был уверен, что мне тоже надо этому научиться.
Однако теперь, работая в сфере разработки ПО, я знаю, что на самом деле все не так. На самом деле хороший разработчик разбивает проект на более мелкие задачи.
Тем не менее, новичку может быть трудно понять, как разбить проект. Если вы не знаете, с какого конца взяться за проект, как же вам его разбить?
Начальная разбивка
Ну, первое, что вам нужно сделать, это посмотреть на определение вашего проекта, а затем разбить его на более мелкие части.
Давайте продолжим использовать пример с калькулятором для создания карточек компонентов:
- Вычислительные функции — MVP
- Получение пользовательского ввода — MVP
- HTML пользовательского интерфейса — MVP
- Стилизация пользовательского интерфейса (CSS) — посыпка
- Слушатели событий JavaScript — MVP
- Добавление анимации для вычислений — посыпка
Обратите внимание, что каждой карточке мы присвоили метку MVP или «посыпка», чтобы было ясно видно, какие карточки являются наиболее важными. Над ними, естественно, нужно работать в первую очередь.
Самое большое преимущество карточек в том, что они упрощают план работ. Это делает проекты менее пугающими, поскольку вы не создаете большое сложное приложение-калькулятор, а делаете 6 небольших проектов, которые объединяются в один большой.
Работая над карточкой, вы перемещаете ее в столбец DOING. Не спешите. Прежде, чем браться за новую карточку, доведите начатое до рабочего состояния.
Но мы еще не закончили с разбивкой. Наш рабочий процесс можно еще больше упростить и улучшить, чтобы гарантировать, что размер проекта не блокирует нас при сборке.
Разбейте каждый компонент на более мелкие чеклисты
Создав высокоуровневые карточки, мы можем разбить эти компоненты на более мелкие задачи. При этом можно использовать чеклисты (контрольные списки), чтобы отслеживать наш прогресс.
В приведенном ниже примере я показал, как делаю это сам. Вы можете делать по-другому, так, как вам удобнее.
Для примера дальнейшей разбивки компонента давайте воспользуемся карточкой «Вычислительные функции».
Поскольку это MVP-задача, а я определил MVP как базовые функции сложения, вычитания, умножения и деления, нам нужно добавить эти функции в чеклист.
Мы разбили нашу карточку на 4 небольших проекта, над которыми мы можем работать. Это куда проще, чем абстрактная и сверхсложная задача создания приложения-калькулятора или даже написания вычислительных функций (название карточки).
Теперь мы можем сосредоточиться на реализации каждой из этих функций. По мере продвижения мы отмечаем галочками сделанное, благодаря чему явно видим наш прогресс и получаем чувство удовлетворения.
Выполнив все четыре пункта, мы можем переместить эту карточку в столбец «DONE» и взяться за следующую.
С этого момента нам просто нужно повторить процесс для каждой карточки. Но вам не обязательно тратить кучу времени, стараясь завершить все задачи в каждой карточке. Это ошибка, которую я сам допустил в начале пути.
Не застряньте, доводя все до совершенства
Занимаясь карточками и задачами в них, не застряньте на бесконечном доведении до идеала каждой маленькой детали.
Из-за этого можно застрять еще на этапе планирования и так и не перейти к этапу программирования. Или же это сделает этап программирования слишком жестким. Вам нужно пространство для маневра в ваших проектах.
Работая над своими проектами, я обнаружил, что мне часто приходилось добавлять больше карточек и задач по мере продвижения. Это неизбежно. Вы впервые что-то создаете, поэтому не можете изначально точно знать, что нужно построить.
Например, при первоначальном планировании у вас может не быть карточки стилей. Но после того, как вы закончите карточку HTML, вы, вероятно, ее добавите.
Так что не зацикливайтесь на том, чтобы сделать план идеальным. Сделайте его достаточным, чтобы вы могли начать. По ходу дела вы всегда сможете внести коррективы.
Вы также можете использовать столбец BUGS / NOT SURE HOW TO DO, чтобы поместить туда карточки, которые вы еще не можете выполнить или на которых вы застряли. Это поможет вам продолжать двигаться.
Начните создавать собственный проект
Теперь у вас есть все, чтобы приступить к планированию и созданию своего проекта. Надеюсь, эта статья сделала концепцию создания проектов менее абстрактной и пугающей для вас.
Ключевыми моментами являются четкое определение проекта, настройка рабочего процесса, а затем разбиение проекта на более мелкие компоненты.
Благодаря этому проект не будет казаться огромной горой, на которую нужно взобраться. Он будет больше напоминать лестницу, каждая ступенька которой помогает вам достичь цели.
И если где-нибудь на r/learnprogramming вы натолкнетесь на просьбу о совете от человека, который пытается выбраться из туториального ада, не советуйте ему просто начать строить собственные проекты. Лучше расскажите, как их планировать и создавать.
Архитектурный проект: как создаются сложные программные продукты
Что это? Архитектурное проектирование в программировании можно сравнить с архитектурным проектом здания. Без него можно обойтись, если речь идет о строительстве беседки, сарайчика для тяпок и лопат. Если же мы хотим построить большое, красивое, функциональное здание, проект необходим. С программами точно так же: простой лендинг можно собрать «на коленке», серьезный продукт – только с помощью архитектурного проекта.
Как работает? Существует несколько подходов к архитектурному проектированию. Каждый из них предназначен для решения определенного круга задач: многослойные, многоуровневые, микросервисные архитектуры. Подробнее читайте в нашем материале.
Что такое архитектурный проект в программировании
Архитектура ПО – это, в принципе, несложная система, с которой справятся инженеры даже с маленьким опытом работы. При этом непросто дать официальное определение самой системе, а точнее, разделить проект и архитектуру, потому что архитектура является одной из частей проекта.
Что такое архитектурный проект в программировании
Дейвид Гарлан и Мэри Шоу в своей книге An Introduction to Software Architecture написали, что архитектура представляет собой особенный этап проекта. Кроме того, перед тем как заниматься созданием алгоритмов и упорядочиванием информации, надо решить одну обязательную задачу – организовать общее устройство системы.
Во время этого процесса разрабатывается общая структура организации концепции и руководства, выбираются протоколы и способы синхронизации, доступа к информации, упорядочиваются функции системы между элементами, происходит физическое распределение, соединение компонентов проекта, масштабирование, улучшение производительности, выбор самого лучшего варианта из всех возможных.
При этом архитектура не находится в рамках структуры программы. Специалисты из команды разработчиков архитектур IEEE утверждают, что архитектура – «концепция системы высочайшего уровня в своей среде». Исходя из этого определения, архитектура включает в себя единство концепции, экономическую целесообразность ее воплощения, эстетику программирования и дизайн.
В Rational Unified Process (RUP) архитектура концепции программы (в этой конкретной точке) – устройство или структура значимых элементов системы, которые связаны друг с другом через интерфейсы, где основа элементов – это последовательно уменьшающиеся компоненты и интерфейсы.
Развитие архитектурного проектирования
Создание архитектурных проектов зародилось намного раньше, чем изобрели компьютеры.
Эта деятельность включает в себя два понятия, которые являются проявлениями одного и того же процесса:
- Архитектура – задача.
- Проектирование – средство реализации задачи.
Как правило, при упоминании архитектуры, особенно если речь идёт о классическом периоде её развития, сразу вспоминаются знаменитые строения, такие как Эйфелева башня, Биг Бен и прочие.
Если говорить о современной архитектуре, то сейчас главная задача стоит в создании функционального здания, а эстетика фасада отходит на второй план.
Такой подход объясняется тем, что человеческое сознание поменялось, и теперь важнее не созерцательное отношение к жизни, а действенные формы существования, за счёт чего поставленные цели достигаются значительно быстрее.
Проектирование представляет собой вид деятельности, направленной на разработку уникального продукта или услуги, чередование пунктов создания которого зависит от внешних условий. К тому же они определяют его итоговые положительные и отрицательные качества.
Сфера проектирования стала наиболее распространённой как современная и продуктивная форма деятельности – проект.
Архитектурным проектированием называется активность, главная задача которой состоит в разработке архитектуры во время реализации проекта.
Архитектурное проектирование программного обеспечения в том виде, под которым чаще всего оно понимается, ставит перед собой задачу создания артефакта (архитектуры), необходимого для осуществления поставленных целей деятельности компании, пользующейся программой для выполнения необходимых процессов.
Стоит отметить, что в современном мире многое зависит от сферы информационных технологий в целом, а в частности от разнообразных программ, которые:
- немного или полностью заменяют человеческий труд и выполняют рутинные задачи, на которые зачастую уходит много сил и времени;
- дают возможность обмениваться различной информацией через сеть интернет;
- повышают эффективность использования не только человеческих ресурсов, но и расходов, которые идут на содержание недвижимости и прочего.
Программное обеспечение – это главный компонент практически всех современных высокотехнологичных доменов (сотовая связь, видеотрансляции, охранная деятельность, управление транспортным и другими видами движения и т.д.) деятельности. В наше время вряд ли найдётся организация, которая не применяет в своей работе информационные технологии.
Абсолютно каждая компания, от предприятий малого бизнеса до государственных традиционных, консервативных по своей сути, общественных, финансовых, социальных организаций всячески стараются перевести все рутинные задачи на автоматическое выполнение. К тому же большое количество из них просто не смогут функционировать без использования специальных программ. Что уж говорить о самых современных компаниях и их зависимости от информационных технологий.
Такую проверку проходят только программы, которые создавались и внедрялись после того, как прошли через этап создания архитектуры ПО.
Развитие архитектурного проектирования
Этот период и является главным отличием «одноразовой» программы, предназначенной для заполнения пробелов, от полноценного продукта, на развитие и использование которого компания собирается отдать довольно много времени из своего жизненного цикла.
Фредерик Брукс, классик области информационных технологий, в своих работах выделил такие отличительные особенности программы от программного продукта:
- максимально обобщённый диапазон и виды входных данных;
- тщательная проверка;
- наличие всех необходимых документов;
- на создание и обслуживание программного продукта уходит намного больше времени.
Главные принципы архитектурного проектирования
Если при разработке архитектуры программного обеспечения применяются разнообразные технологии проектирования, то так не только становится проще данный процесс, но и легче и быстрее создаётся продукт. При этом не надо вкладывать огромные деньги, а все усилия и расходы для разработки и дальнейшего обслуживания минимальны.
- Разделение проблем. Суть принципа в том, что программа должна отличаться на основе деятельности программного продукта. К примеру, подобное можно осуществить, если отделить бизнес-модель от части создания, чтобы работники одного отдела не переживали за другие команды
- Инкапсуляция. Так можно отделить одну часть приложения от других её составляющих. Данным образом можно менять проект, не опасаясь, что изменения коснутся других частей приложения.
Скачивайте и используйте уже сегодня:
Топ-30 самых востребованных и высокооплачиваемых профессий 2023
Поможет разобраться в актуальной ситуации на рынке труда
Подборка 50+ ресурсов об IT-сфере
Только лучшие телеграм-каналы, каналы Youtube, подкасты, форумы и многое другое для того, чтобы узнавать новое про IT
ТОП 50+ сервисов и приложений от Geekbrains
Безопасные и надежные программы для работы в наши дни
- Избегайте повторений. С помощью этой технологии можно избежать повторений функциональности, необходимой одному приложению. Так у вас не будет дубликатов, и можно будет создать один фрагмент кода для одного компонента. Данный принцип нужен для упрощения приложения.
- Принцип наименьшего знания(LoD (Закон Деметры)). С его помощью не возникает взаимозависимости между составляющими за счёт того, что один компонент не знает внутреннюю архитектуру программы, в которой есть другие составляющие и объекты.
7 критериев качества архитектуры проекта
Вообще нет общего понятия «архитектура программного обеспечения». Однако, как правило, разработчики могут самостоятельно понять, хороший перед ними код или плохой. Хорошая архитектура должна приносить как можно больше выгоды, упрощать процесс создания и обслуживания программного обеспечения.
Критерии качества архитектуры проекта
Когда у программы качественная архитектура, её проще дополнять и менять, проводить тестирование, регулировать, изучать. Получается, что вполне можно создать список логичных и универсальных критериев.
Эффективность системы
Главная цель программного обеспечения – справляться с поставленными задачами и качественно делать свою работу вне зависимости от условий. В данный пункт попадают такие критерии, как надёжность, безопасность, продуктивность, возможность выдерживать увеличенные нагрузки и прочее.
Гибкость системы
Любую программу надо периодически изменять, потому что появляются новые требования. Если внесение изменений в приложение происходит быстро и удобно, а также не приводит к возникновению проблем и ошибок, то такая система считается гибкой и конкурентоспособной. Так что надо заранее продумывать момент возможных изменений. Задайте себе вопрос: «А что случится, если нынешнее архитектурное решение будет неправильным?», «Сколько кодов надо будет поменять в случае внесения корректив?».
От переделки одной части кода не должны пострадать другие его фрагменты. Желательно, чтобы архитектурные решения были гибкими, а возможные ошибки должны наносить как можно меньше вреда.
Расширяемость системы
Способность дополнять программу новыми компонентами и опциями, не меняя при этом её основную концепцию. На первых порах при разработке надо наполнять систему только основой и самыми важными функциями (принцип YAGNI — you ain’t gonna need it, «Вам это не понадобится»). Однако при этом у вас должна быть возможность запросто дополнить программу, если это потребуется.
Требование о том, чтобы архитектура программы была гибкой и поддавалась изменениям и усовершенствованию, считается очень важным, поэтому есть даже «Принцип открытости/закрытости» (Open-Closed Principle — второй из пяти принципов SOLID): программные сущности (классы, модули, функции и т.п.) должны быть открытыми для расширения, но закрытыми для модификации.
То есть программу надо создавать так, чтобы во время изменения и внесения новых опций достаточно было написать новый код и просто его добавить, не трогать при этом существующий код. Таким образом, новые требования не станут причиной изменения уже имеющейся логики, а смогут реализоваться через внесение корректировок в систему. Данный принцип – это основа «плагинной архитектуры» (Plugin Architecture).
Масштабируемость процесса разработки
Не менее важно при создании архитектурного проекта делать всё быстро, а добиться этого можно, увеличив количество участников его разработки. Архитектура должна быть такой, чтобы можно было распределить между людьми работу по созданию программы.
Тестируемость
Когда код легко проверить на ошибки, в нём их практически не останется, и функционировать программа будет хорошо. При этом проверка необходима не только для выявления погрешностей в коде, но и в качестве ориентира, который помогает создавать качественный и привлекательный дизайн, а также оценивать его качество. Относитесь к принципу тестирования как к одному из главных критериев качества визуального образа программы.
Даже если вы не написали ни одного тестового кода, проверка в 90 % случаев покажет, насколько дизайн хороший или плохой. Есть целая методология создания приложений через тесты, название которой говорит само за себя – «разработка через тестирование» (Test-Driven Development, TDD).
Возможность повторного использования
Намного разумнее разрабатывать такую систему, из которой можно будет брать её составляющие и переносить в другие программы.
Структурированный, читаемый и доступный код
Зачастую над созданием любого программного обеспечения трудится целая команда сотрудников, и люди в процессе могут меняться. Когда работа над написанием программы завершается, её сопровождением чаще всего занимаются специалисты, которые не участвовали в разработке. По этой причине надо так выстраивать архитектуру, чтобы программу быстро смогли понять другие люди.
У проекта должны быть структура и грамотно оформленный код, все необходимые документы, отсутствовать дублирование. В необычной и уникальной системе сложно разобраться. Есть даже принцип наименьшего удивления — Principle of least astonishment. Как правило, его применяют при разработке пользовательского интерфейса, но и при создании кода программы его тоже можно придерживаться.
Критерии качества архитектуры проекта
Стоит упомянуть признаки плохого архитектурного проекта:
- В него сложно внести коррективы, так как любые перемены влияют на множество других частей программы (жесткость, Rigidity).
- Из-за внедрения новых кодов «ломаются» фрагменты системы (хрупкость, Fragility).
- Практически невозможно применить код в другой программе, потому что «вытащить» его из системы очень непросто (неподвижность, Immobility).
Зачем разрабатывать архитектуру проекта
Раньше при создании программ не создавали архитектуру проекта. Первое время это считалось правильным и удобным, потому что не надо было тратить время на «лишнее» планирование, и было быстрое прототипирование. Однако чем сложнее становились приложения, тем менее податливыми и управляемыми они были, и любое новое внедрение требовало немалых денег.
Спустя годы эволюции приложений программисты смогли разработать хорошие методы, которые помогали избавиться от минусов создания проектов без архитектуры.
Вот самые популярные из них:
- Многослойная архитектура (Layered Architecture).
- Многоуровневая архитектура (Tiered Architecture).
- Сервис-ориентированная архитектура (Service Oriented Architecture — SOA).
- Микросервисная архитектура (Microservice Architecture).
Тест на определение компетенций
Чек-лист «Как избежать обмана при трудоустройстве»
Инструкция по выходу из выгорания
Чтобы зарегистрироваться на бесплатный интенсив и получить в подарок подборку файлов от GeekBrains, заполните информацию в открывшемся окне
Не лишним будет детальнее узнать о каждом подходе.
Многослойная архитектура проекта
Главное отличие этого подхода в разделении ответственности. В любой программе есть слои, которые находятся друг на друге, у каждого из них есть своя обязанность, и он за неё отвечает.
Многослойная архитектура проекта
Архитектурный проект имеет следующие слои:
- Слой представления (Presentation Layer). В нём находится пользовательский интерфейс, задача этого слоя – давать положительный пользовательский опыт.
- Слой бизнес-логики (Business Logic Layer). Название говорящее: в нём находится бизнес-логика программы. Он разделяет UI/UX и расчёты, связанные с бизнесом. Таким образом, можно быстро и просто поменять логику, чтобы подстроиться под новые бизнес-требования, которые постоянно меняются, и при этом другие слои не страдают.
- Слой передачи данных (Data Link Layer). Он ответственен за взаимодействие с постоянными хранилищами, среди которых базы данных, а также совершение обработки информации, не имеющей ничего общего с бизнесом.
Данные и компоненты управления попадают в каждый слой в дизайне, переходя от одного к другому. Помимо этого, система увеличивает степень абстракции и может даже стабилизировать работу программного обеспечения.
- В отличие от других подходов, этот легче реализовать.
- Возможность абстракции за счёт разделения ответственности между слоями.
- Благодаря изоляции, при изменении одного уровня другие остаются нетронутыми.
- Слабая связанность улучшает управляемость программой.
- Нет возможности сильно увеличить масштаб.
- У программ с таким подходом монолитная структура, поэтому внести коррективы в неё довольно сложно.
- Информация в любом случае переходит по каждому уровню, даже если не надо затрагивать определённые слои.
Многоуровневая архитектура проекта
Данный архитектурный метод делит систему программы по принципу «клиент-сервер». У архитектуры может быть один, два и более слоёв, которые разделяются между поставщиком информации и потребителем.
В этом методе применяется шаблон Request Response, служащий для того, чтобы между слоями была связь. Главное отличие от многослойной архитектуры в том, что данный вариант нужен для увеличения масштаба, который может быть горизонтальным (масштабирование сети при помощи высокопроизводительных узлов), вертикальным (масштабирование каждого узла через увеличение его производительности).
Одноуровневая система
Такой подход даёт возможность единой системе работать и на стороне сервера, и на стороне клиента. Благодаря этому развёртываемость происходит быстрее и проще, а скорость соединения выше. Помимо этого, пропадает необходимость в межсистемном взаимодействии (Inter-system communication — ISC).
Подобный подход применим только для маленьких приложений, рассчитанных на одного пользователя.
Двухуровневая система
В этой системе есть две физические машины: сервер и клиент. За счёт неё изолируются операции управления данными, их обработки и представления.
- У клиента уровни презентации, бизнес-логики и передачи информации.
- Сервер отвечает за хранилище и базу данных.
Трехуровневая и n-уровневая системы
В подобных архитектурах высокая масштабируемость по обоим направлениям (горизонтальному и вертикальному). Разработка n-уровневой программы стоит дороже, зато её производительность в разы лучше. По этой причине её часто используют в крупных и комплексных программах.
Трехуровневая и n-уровневая системы
Данный метод хорошо взаимодействует с современной сервис-ориентированной архитектурой, за счёт чего можно разрабатывать сложные модели. Так как создание такой системы требует много времени и инвестиций, применять её лучше для сложных программ, которые должны обладать высокой производительностью и масштабируемостью.
Сервис-ориентированная архитектура (SOA)
Такой архитектурный проект включает в себя составляющие и приложения, связанные между собой определёнными сервисами.
В него входят 5 компонентов:
- сервисы (Services);
- сервисная шина (Service Bus);
- сервисный репозиторий (Service Repository catalogue of services);
- безопасность SOA (SOA Security);
- управление SOA (SOA Governance).
Пользователь отправляет запрос через традиционный протокол и формат данных через интернет. Запрос идёт на обработку в ESB (enterprise service bus — сервисная шина предприятия), являющуюся самым важным элементом сервис-ориентированной архитектуры, который ответственен за оркестровку и маршрутизацию.
Через сервисный репозиторий ESB отправляет запрос в специальный сервис, у которого есть связь с другими составляющими и базами данных, для создания полезной нагрузки (данных) ответа.
Получение полного ответа должно быть согласовано с правилами управления и безопасности SOA, чтобы передача данных была максимально правильной и надёжной.
Зачастую, сервисы бывают двух видов:
- Атомарные сервисы (Atomic services) дают те опции, которые невозможно потом изменить.
- Композиционные сервисы (Composite services). В них сочетаются несколько атомарных сервисов, благодаря чему создаётся сложная составная функциональность.
Существуют следующие типы сервисов:
- Организационные сервисы (Entity service).
- Доменные сервисы (Domain Service).
- Вспомогательные сервисы (Utility Service).
- Интегрированный сервис (Integrated Service).
- Сервис приложений (Application Service).
- Сервис безопасности (Security Service).
Mикросервисная архитектура проекта
Этот подход отличается тем, что программа создаётся как комплекс маленьких сервисов. Каждый из них действует в своём процессе и соединяется с легковесными механизмами, как правило, API для HTTP-ресурса.