В этой статье я коснусь некоторых проблем заказной разработки, как мы эти проблемы решаем, и как мы постепенно перешли к идее создать it продукт — веб-платформы с подходом, где во главе угла стоит SQL.
Демостенд нашей веб-платформы можно посмотреть здесь.
Делая очередной проект по схеме заказной разработки, когда код пишется под проект на неком фреймворке, сталкиваешься с одним и тем же набором проблем.
Ожидания заказчика по срокам проекта всегда сильно превосходят реальность. Полный стек разработки подразумевает взаимодействие множества людей, возникают микрозадержки, и в итоге все это растягивается (даже без учета периода отладки).
В такой схеме программист — самое узкое звено, и именно оно должно работать на полную мощность без ненужных простоев.
Разработка с нуля и полный стек подразумевают больше мест, где можно допустить ошибку. Особенно это проявляется при попытках «ускорить» проект. Добавляются новые программисты, какие-то решения по требованиям принимаются необдуманно, прямо на ходу.
В итоге это ведет все к ошибкам, долгой отладке и лишним нервам.
Отладка растягивается из-за того, что ошибка может быть где угодно расположена по стеку.
Очень часто заказчик сравнивает заказную разработку с созданием аналогичного продукта на готовой системе — какой-либо CMS. При этом совершенно не учитывается гибкость и возможность дальнейшего развития.
Заказная разработка - это всегда дорого, т.к. количество людей требуется в этом процессе гораздо больше, нежели в сборке из готовых модулей.
При этом квалификация этих людей требуется более высокая высокая, чем при работе с модулями на CMS в общем случае.
Неправильный доступ к данным, гигантские неявные циклы в коде могут привести к проблемам производительности. Сложно искать подобные ошибки по проекту, когда их можно внести на любом уровне (в хранимых процедурах, бизнес-логике, контроллерах).
Подробнее проблема качественного кода разобрана в другой статье.
Должно быть довольно хорошее понимание этих моментов у каждого разработчика, иначе в дальнейшем можно получить проблемные места по производительности где-то в коде проекта.
При этом подготовка одного программиста по полному стеку довольно непростая история. И далеко не сразу вопросы производительности для него становятся актуальными.
Уход человека из команды может очень сильно сказаться на дальнейшем качестве проекта, и здесь сложно что-то изменить, т.к. в любом случае есть такие люди, которые знают о проекте больше других, и никакая документация не сможет компенсировать для проекта их потерю.
В нашем случае заказная разработка — не сахар.
Возможно, есть такие команды, которые делают все легко и просто (ну или поддерживают такое ощущение у потенциального клиента).
Если же эти проблемы наложить на неуемные аппетиты заказчика по кастомизации и гибкости, то картина получается совсем грустная. Долго, дорого, с ошибками делаем проект, переделываем под новые требования-хотелки клиента, пока в итоге не заканчивается бюджет, и проект замораживается на неопределенный срок.
Эти проблемы были порождением нашего подхода, и необходимо было что-то менять именно в нем, возможно от чего-то отказаться.
Особенно, конечно, удручает ситуация, когда относительно типовые вещи (например, добавление поля на редактирование в таблицу) делаются очень долго. Нужен был новый способ, который позволил бы делать эти правки легко и без лишних хлопот различных специалистов.
Что хочет от нас заказчик, когда создает свой it продукт?
Один из главных факторов — это деньги. Он хочет сэкономить и понимать свои будущие расходы на развитие проекта.
Для большинства заказных проектов стоимость изменений постепенно растет. В начале быстро движемся, реализуем все необходимые возможности. Но по мере использования проекта, изменение/добавление возможностей делать все сложнее/дороже.
Скорость внедрения идет рука об руку с экономией. Все, что долго внедряется, и бюджета требует больше.
Умный заказчик инстинктивно понимает, что ему не нужен долгий тяжелый проект, в котором можно надолго застрять. Нужно сделать быстро что-то небольшое, внедрить, получить обратную связь (и свернуть проект, если нет результата).
Если же делать большой проект год-полтора, то надо вбухать большую сумму, при этом нет никакой гарантии, что самолетик полетит.
Продукт можно быстро менять, а не ждать внедрения каждой возможности неделями.
В проекте может быть очень много гипотез, которые заказчик хочет проверить на своих пользователях. И важно успевать за ритмом хотелок заказчика. Вчера придумали, сегодня описали, завтра внедрили и пользуемся. Так в идеале должны внедряться мелкие доработки.
Совсем идеал — это когда заказчик некоторые моменты может по-горячему поправить в системе (конечно, с пониманием и полной ответственностью за свои действия) — как мы это делаем в Excel, меняя формат таблиц или добавляя новую формулу.
Забегая вперед, скажу, что мы исходим из того, что заказчик может знать SQL, а значит, может при желании много что изменять в нашей системе.
Именно по этой причине заказчик выбирает разработку под свои нужды.
В заказной разработке можно сделать что угодно и как угодно.
Это пункт, где по умолчанию к заказной разработке клиент выдвигает максимально высокие требования: уникальный дизайн, все требования бизнес-аналитика заказчика, плотные интеграции с внешними системами.
Важный нюанс — кастомизация в будущем под вновь возникающие потребности бизнеса. Если это совсем не учитывать в начале, то может получиться хорошая система, которую никак нельзя поменять (очень дорого), либо изменение делается через дичайшие костыли.
В идеале для заказчика проект никак не должен зависеть от поставщика услуг. Это достигается за счет использования широко известных проверенных технологий, чтобы иметь достаточно вариантов для найма подходящего специалиста. Второе по важности — это документация, которая создается (или не создается) под проект по мере развития системы.
В нашей платформе для поддержки решения надо знать всего лишь 2 распространенных технологии: MS SQL Server (бизнес-логика и обработка данных) и Bootstrap (стилизация интерфейса)
На этапе запуска заказчик ожидает, что продукт должен быть хорошо протестирован и не содержать ошибок. В теории — да. Но посмотрите на количество патчей готового продукта ОС Windows (возможно сравнение некорректное ввиду сложности и масштабов, но суть примерно та же).
Здесь важнее понимать итеративную природу проекта, и с понимаем относиться к ошибкам (нашли — исправили — работаем дальше).
В любом случае разработчик, со своей стороны, должен в целом как-то уменьшать риски возникновения ошибок, не влияя сильно на раздувание бюджета.
Что может предложить веб-разработчик такому заказчику?
По большому счету у него 2 варианта:
Оба решения имеют свои достоинства и недостатки.
Готовое решение сложно в дальнейшем кастомизировать, а заказная разработка это очень долго и дорого.
Главная дилемма заказчика — хочется быстро получить готовое решение, но при этом оставить возможность глубокой кастомизации под себя и возможность в дальнейшем развивать свой продукт.
Разработчику в идеале хорошо бы сделать свой типовой продукт и продавать его всем желающим. Но есть свои нюансы:
Постепенно пришло понимание, что заказная работа по фуллстеку — это сложно масштабируемое низкорентабельное и довольно неблагодарное дело:
В идеале решение виделось таким:
Меньше технологий — дешевле поддержка, быстрее обучение, более надежно работающее решение.
В нашей старой системе учета, которую мы сделали под свои нужды, был модуль Метрики.
В нем я реализовал подход, когда метрика — это просто некая хранимая процедура на SQL, которая визуализируется в таблицу. В таблице могут быть вложенные таблицы, которые также создаются через SQL.
В итоге, чтобы создавать такие метрики не нужно менять код приложения, делать обновления PROD-версии. Меняем данные в таблицах, создаем процедуры и проверяем на сайте.
Тут важный момент в том, что метрики создаются постепенно (сейчас их более 250 и большинство из них уже не актуальны). Таким образом, такой подход экономил кучу времени (в сравнении с тем, если бы это было сделано через код приложения, например, через LINQ, EF).
Параллельно у нас был JS компонент Таблица, который позволял относительно быстро собрать таблицу управления некой сущностью (CRUD): настроили JSON, создали метод Контроллера, прописали методы в бизнес-логике и DAL и таблица готова.
Пришла идея повторить SQL-подход на таблицах:
Именно это в будущем и легло в основу построения любого компонента конструктора для создания сайтов:
Пока не было идеи создать полноценную платформу. Было большое желание максимально ускорить создание таблиц и уменьшить количество дурацких ошибок, размазанных по всему стеку. Вместо 3-4 часов тратить на это 30-40 минут.
В итоге задачу мы эту решили, но не стали останавливаться на достигнутом и попробовали реализовать другие типовые элементы. Основные компоненты — это статичные страницы и формы.
В тот момент ключевой проблемой на пути к возможности создания платформы была работа форм. Изначально было обходное решение: давать платформу как проект доработки в виде solution на ASP.NET. Но в этом случае мы получали проблемы обновления и все недостатки заказной разработки на полном стеке.
После адаптации форм под новый подход с SQL управлением стало понятно, что и все остальное мы сможем решить по аналогии: выгрузку документов, менеджер ресурсов, дашборды, чаты и т.д. Началось постепенное создание компонентов платформы.
Параллельно мы делали и клиентские проекты уже на базе конструктора для создания сайтов.
Возникали более узкие вопросы: внедрение SignalR, интеграции, кастомизация внешнего вида. Все эти новые потребности мы решали для проекта заказчика, но также это шло и в копилку нашей платформы, т.к. мы расширяли ее возможности и делали ее более гибкой.
При всем этом основная идея была в том, чтобы не перегружать саму платформу какими-то узкими элементами, заточенными только под потребности конкретного заказчика.
Т.е. в платформе создавался некий механизм, которым можно управлять через SQL, а этот самый SQL уже писался под проект.
В итоге получилось относительно стабильное ядро, которое не меняется под проект и все основные изменения идут через хранимые процедуры, которые в целом позволяют реализовать практически любую логику.
Две ключевые проблемы на этом этапе:
Для API мы сделали 2 подсистемы: входящие методы API и исходящие запросы к внешним API.
Входящие методы — это, по сути, метод контроллера, принимающий все запросы, и, по коду действия определяющий хранимую процедуру обработки. Эта процедура обрабатывает входные данные и выдает результат, который отдается запрашивающей стороне в JSON, XML или plain text.
C исходящими запросами все немного сложнее. Сначала нужно подготовить запрос к внешней стороне (это одна хранимая процедура — request), а затем обработать ответ от внешней стороны (это другая хранимая процедура — response).
Отправлять запросы можно по POST, GET, параметры можно передавать в теле, header или через url.
Для вызова нестандартных действий сначала попробовал, но отказался от внедрений сборок в SQL Server. Это громоздко и сложно переносимо, плюс требует дополнительных внешних настроек и создает зависимости от внешней среды.
В итоге было принято решение внедрять концепцию Внешних действий: платформа ожидает от хранимых процедур некоторых дополнительных select, в которых передаются нужные команды, например, отправить СМС.
Таким образом, мы выполняем «в SQL» действия, которые на деле совершаются уже после выполнения хранимой процедуры.
Ключевая идея платформы — возможность кастомизации бизнес-логики при сохранении общего подхода (SQL-процедуры декларативно управляют всем).
Внутренний код платформы не меняется под проект, только SQL-код создается под конкретную бизнес-логику проекта. Это делает возможным обновление платформы без необходимости как-то объединять кастомные проектные доработки (частые изменения) с доработками по ядру (редкие изменения).
Также этот подход позволил упростить создание типовых решений. В нашем случае любое готовое решение — это, по сути, просто большой кусок SQL-кода (определения таблиц, хранимые процедуры, SQL функции и данные таблиц).
Мы создали дополнительные инструменты внутри платформы, упрощающие перенос частей проекта на другую базу в виде SQL скриптов.
Постепенно создаем свои типовые решения и предлагаем их внедрение в рабочие проекты (например, компонент Блог или База знаний).
Кое-что пришлось оставить за бортом. Например, сильную нетиповую кастомизацию внутренних страниц в плане дизайна.
Лендинги в системе могут быть любые. Они сделаны так, что код лендинга просто добавляется целиком и адаптируется в платформе.
Кастомизация внешнего вида возможна через настройку темы, но все же имеет ограничения. Главное меню находится слева (либо полоска сверху), верхняя полоска имеет стандартный вид для платформы.
Сильно кастомные проекты на внешний вид — это не про нас. Мы даем большую гибкость в плане изменения бизнес-логики и хороший внешний вид по умолчанию, что подходит для 95% проектов.
По опыту, как-то так получилось, что проекты с повышенными требованиями по дизайну, самые проблемные и сильно рискованные. Зачастую за придирками по дизайну часто стоит полное непонимание процесса создания продукта со стороны заказчика, смещение фокуса внимания с важных вещей на несущественные детали.
Дизайн и внешняя привлекательность важны, но для бизнес-систем я не вижу особой потребности в уникальности дизайна. Это скорее личные особенности владельца продукта, которые не идут на пользу этому самому продукту.
В общем, мы пожертвовали некоторой гибкостью в отношении дизайна, но оставили возможность изменений через CSS и JS.
При этом центральная рабочая область может быть сверстана как угодно. Компонент Форма позволяет использовать расположение элементы по умолчанию, но также позволяет внедрить свою кастомную разметку на Bootstrap 4.
Для полного освоения системы нужно знать 2 технологии: MS SQL и Bootstrap 4. SQL обеспечивает нам пластичность бизнес-логики, а Bootstrap — гибкость вывода данных в интерфейсе (при этом можно обойтись по умолчанию и без него).
Почему мы выбрали SQL? Разработка своего языка — это сложно и непонятно зачем, да и разработчику придется осваивать новое для себя. По субъективному ощущению, большинство программистов в том или ином объеме знают SQL (ну как минимум, сталкивались с ним в ВУЗе).
Для алгоритмических задач SQL позволяет делать основные действия: условие, циклы, типовые функции.
SQL — средство извлечения данных из базы данных. Используя его как основу, мы как минимум снижаем возможные риски проблемы производительности (конечно, это не панацея, но гораздо лучше Lazy loading и неоптимизированных запросов в LINQ).
Также компоненты за один вызов хранимой процедуры возвращают сразу несколько select. Это также уменьшает время на обработку запросов, требуется открывать меньше соединений с БД.
Внутри не используется тяжеловесная ORM (например, Entity Framework, Linq2SQL). Все запросы написаны в SQL и оборачиваются в объекты через Dapper (что сравнимо по скорости обработки с DataReader).
Основная разработка ведется через кабинет администратора.
Потенциально можно делать горячие правки и через телефон (интерфейс адаптивен под мобильные).
Конечно, у полноценной IDE есть свои большие плюсы. Мы постепенно добавляем различные возможности в наш sql-редактор (подсветка кода, тестовый запуск хранимых процедур, вывод параметров запуска, полноэкранный режим и др.).
Мы уменьшили количество людей на проектах. Для проекта мы привлекаем не более 2-3 человек (а раньше было до 10 человек). Это упрощает контроль, уменьшает ненужные взаимодействия на проекте и снижает себестоимость выполнения работ.
Существенно увеличилась производительность отдельного разработчика - ведь теперь ему можно сконцентрироваться на реализации бизнес-логики, а не отдельных мелких элементах реализации.
Крайне важный момент — платформа шлифуется с каждым проектом.
Бывают внутренние ошибки выявляются в ходе реализации проекта. Они исправляются, и эти правки улучшают качество не только конкретного проекта, но и других проектов, сделанных на платформе. Постепенно появляются новые возможности и настройки кастомизации, которые в каждом проекте могут быть использованы уникальным образом (т.к. изменяются через хранимые процедуры).
Это одно из главных преимуществ развития своего продукта по сравнению с разработкой без своего базового продукта — вы непрерывно улучшаете его качество попутно. Решение каждой системной проблемы не теряется, а интегрируется в продукт.
Чем меньше мест, где разработчик может допустить ошибку, тем быстрее можно найти эту ошибку. В нашем случае 90% ошибок — это неточности в SQL. Именно там в первую очередь нужно искать проблему. Это также влияет на время отладки решения и, в целом, на сроки этапа.
На проектах одна из задач — это выявление неточностей в проекте (внешний вид, бизнес-логика) и проработка этих моментов должна решаться на платформенном уровне, чтобы была возможность за счет простых средств (CSS классы или настройки в ХП) решать эти моменты в дальнейшем. Правда, это ведет к побочному эффекту — распуханию документации, т.к. каждая подобная настройка требует описание ее применения.
Дополнительным плюсом для нас стало более простое обучение новых разработчиков для платформы. Если человек знает SQL и что-то слышал о HTML, то в целом не будет особого труда обучить его работе на платформе. Раньше обучение полному стеку могло занять 3-6 месяцев. Сейчас, в целом, при плотном изучении и практике можно освоить основные возможности платформы за 1-2 недели.
Снизилась себестоимость работ.
От разработчика в большинстве случаев скрывается большая часть забот по выводу данных. Если не требуется особая кастомизация, то решения можно собирать очень быстро и это не требует больших затрат (особенно, если человек уже хорошо знает нюансы платформы).
Многие моменты делаются по умолчанию, разработчику не нужно думать о мелких деталях вывода таблицы. Его задача — правильно настроить хранимую процедуру, а платформа обеспечивает работу таблицы в соответствии с его настройками в хранимых процедурах.
Правки делает один человек, нет нужды задействовать сложный цикл обновлений бизнес-логики. Если заказчик сам владеет SQL, то какие-то элементы он сам может менять в системе.
Заказчик изначально видит демо и примеряет это на свой проект. Его ожидания по внешнему виду формируются на самой ранней стадии. И не возникает в будущем сильного расхождения между желаемым и действительным.
В целом платформу можно поставить на Win хостинг за 300 руб. в месяц и этого вполне хватит на начальном этапе развития проекта (а дальше — все зависит от трафика и количества данных в БД).
В заказной fullstack-разработке мы всегда использовали VPS (и расходы по памяти были больше, видимо, из-за неоптимальных мест, которые иногда случаются).
Процесс непрерывного улучшения затягивает. Постепенно привыкаешь к процессу внедрений и шлифовки компонентов.
Нам еще многое предстоит сделать в плане адаптации разработчика в платформе, улучшению документации и проработки системных инструментов (диагностика БД, инструменты стресс тестирования хранимых процедур и т.д.).
В данный момент мы прорабатываем пробы соединения с другими базами, т.е. чтобы можно было сделать обработку данных в платформе из «неродных» баз данных (PostgreSQL, MySQL, Oracle).
Также важное направление — это работа на Linux (в целом демостенды на Linux уже есть, но еще требуют проверки всех возможностей платформы). Сейчас в основном система используется на Win хостинге либо на VPS с Windows Server.
Ну и самое главное — это создание слоя бизнес-модулей. Т.е. это уже укрупненные блоки, ориентированные на бизнес-задачи — учет кадров, отчет БДДС, генерация счетов и другие компоненты, которые в итоге собираются в подсистемы.
В новом проекте можно не делать с нуля некую подсистему, а взять за основу наш существующий блок (например, отчет БДДС) и его дальше адаптировать под свои нужды. Любой созданный на платформе компонент — это пакет SQL, который может быть перенесен в новую БД.
У данного решения можно выделить следующие минусы:
Мы пока в начале пути. Еще многое предстоит сделать.
Но уже можно с определенностью сказать, что у нас есть свой продукт, который мы постепенно шлифуем с каждым новым проектом - проектом заказчика или нашим типовым решением/демо.
Источник: наша страница на vc.ru https://vc.ru/tribuna/173182-na-puti-k-svoemu-produktu-ot-zakaznoy-razrabotki-k-sozdaniyu-svoey-platformy
P.S. Если вы планируете создавать свой продукт в сети, то посмотрите наше большое руководство Как создать IT продукт.