02 августа

Конечно, описать интерфейс, создать дизайн, описать функции системы в ТЗ - это уже большой и важный шаг. Но к сожелению этого не достаточно для того, чтобы иметь уверенность, что система будет работать согласно ожиданиям. Более того, что если я Вам скажу, что как бы хорошо Вы не описывали функциональность системы, шанс того что проект будет провален достаточно высок? Для того, чтобы иметь уверенность в будущем проекта и даже получить документально-подтвержденные гарантии нужно определить НЕфункциональные требования к системе, требования, которые определят минимальное качество, которого будет достаточно, чтобы проект выполнил свою цель.

Это пункты, которые нужно не просто обсудить с разработчиками на словах. Это - часть Вашего договора с ними! Важно подобрать и расписать их именно под Ваш проект. К примеру, если проект представляет собой стартап или MVP для тестов и имеет бюджет порядка 20-30 тысяч долларов на разработку - то требования, помеченные "$$$" будут для Вас неуместными, но есть методы их частичного соблюдения. Компромиссы. В конце статьи я поделюсь также кратким списком требований, который подойдет для создания прототипа - упрощенной версии приложения, непригодной для использования в реальных условиях, но достаточной для анализа и дальнейшей разработки. Там вс практически наоборот, нужно нарушать некоторые требования и использовать специальные принципы.

Без лишних слов делюсь с Вами некоторыми самыми важными нефункциональными требованиями.

Не функциональные требования

(требования к системному качеству)


$$$ Соответствие языку предметной области

Система именования в программном коде должна совпадать с терминологией языка предметной области. (на версии MVP этот язык будет содержаться в схеме данных).

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

Читабельность

Если кратко - это требование, по которому разработчики обязуются писать код, который кто-нибудь кроме них может прочитать. Да, вот так просто, но сверх-важно. Для соблюдения данного пункта будет достаточно соблюдения рекомендаций по стилю кодирования по оформлению кода и рекомендаций выбранного фреймворка по организации файловой системы. Для любого языка программирования уже существует такой набор правил, к примеру в php есть PSR. Читабельность кода, конечно, не повлияет на то, как будет работать ПО. Но программа - это не статическая штука, она постоянно меняется и поддерживается. Так что можно утверждать что от такого простого требования будет зависеть, сколько будет багов в Вашей системе и сколько будет стоить их исправление. Особо нечитабельный код никто не захочет править и даже смотреть. Из моего опыта у большинства проектов именно такой код и его владельцы переплачивают за до смешного простые правки - часто дороже, чем им обошлась изначальная разработка. Это не очень дорогое требование, но часто оно зависит от совести программиста и потому часто нарушается. Оно должно стать частью договора!

Документация к API серверного приложения

Система должна содержать документацию серверных моделей данных а также документацию всех URL ресурсов сервера с возможностью произвести тестовый запрос, увидеть его параметры а также увидеть реальный ответ серверного API.

Данный пункт критически важен для приемочного тестирования. Если у Вас современный проект с отдельным фронтендом - без соблюдения данного пункта бекенд разработчики будут иметь возможность сдать Вам пустышку или очень запутанное API, которое Вы не сможете применить, что еще хуже, ведь перед тем как это выяснить на это потратят время другие наёмные сотрудники!

Мы используем отличное веб-дополнение Swagger - программу, в которой не только прозрачно видно, какие функции выполняет сервер, но так же можно просмотреть структуру базы данных. А самый главный бонус - можно самостоятельно без знаний программирования провести ручное тестирование функций сервера! Если тема интересна - пишите в комментарии, мы напишем отдельную статью на тему API с примерами из реальных проектов.

Документация к ключевым алгоритмам системы

Все ключевые узлы и алгоритмы системы, а также блоки кода, не соответствующие самодокументирующемуся коду должны иметь наглядный и бросающийся в глаза комментариев (в коде) или файл с названием README.md в папке модуля\приложения. Тут ключевое слово - "ключевые". Документация каждой строки кода приведет к сильному повышению стоимости продукта. Потому особенно для стартапов или небольших компаний важно, чтобы архитектор определил самые важные алгоритмы в системе, к которым должна поставляться документация. Её должны понимать не только программисты, но и не технические спецы.

$$$ Распределенность

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

Веб интерфейс, серверное API, административная зона, CDN сервер, сервис полнотекстового поиска - отдельные сервисы.

В будущем подсистемы могут быть распределены в отдельные репозитории.

Система развёртывания

Система должна быстро (в несколько шагов) устанавливаться на Ubuntu системах, на которых предварительно установлен Docker, docker-compose, git и пакетный менеджер.

Система должна содержать настройки доступов к базам данных, подсистемам и внешним сервисам (типа гугл авторизации, сервиса видеосвязи или почтового клиента), настройки безопасности (например, CSRF токен, соль, пароли..).

Система развёртывания хранится в репозитории в СКВ.

Система развёртывания содержит конфигурации базы данных, веб серверов и интерпретаторов.

Система развёртывания должны создавать конфигурации для других систем по шаблону.

$$$ Модульность

Система должна поддерживать заданную модульность, соответствующую принципам LOW COUPLING и HIGH COHESION. Это принципы из не очень популярного (в сравнении с SOLID) набора рекомендаций GRASP, тема для отдельной статьи.

Принципы задания модулей зависят от бизнес-требований к модулям либо по принципу “по модулю на агрегат”.

ВНИМАНИЕ: имеется в виду соблюдение данных принципов на уровне ГРУПП классов (мини-приложений, программных модулей). Соблюдение данного принципа на уровне классов потребует больше времени на реализацию, потому не ожидается на этапе MVP.

Многоуровневая архитектура

Каждый модуль состоит из нескольких слоёв (уровней).

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

Используем архитектуру открытого слоя (слой может обращаться к слою более низкого уровня в обход других слоёв)

Вот основные слои в многоуровневой архитектуре.

Интерфейс

$$$ React, Angular или Vue приложение, состоящее преимущественно из веб компонентов.

*АЛЬТЕРНАТИВНЫЙ ВАРИАНТ: PJAX приложение, упрощенная модель быстрого взаимодействия с пользователем.

Слой Контроллер

Данный уровень

1. Ответственный за получение входящего запроса по протоколу

2. Имеющий строго определенный URL адрес

3. Проводит авторизацию запроса

4. Делегирует обработку запроса определенному сервису.


Соответствует паттерну “Контроллер” из GRASP и принципу “Тонкий контроллер”.

Слой Сервис

Слой с классами типа “Pure Fabrication”, являющимися дополнительной оболочкой для взаимодействия с моделями предметной области. В данном слое размещается логика, связанная с группировкой некоторых операций с моделями для переиспользования или любая логика, не относящаяся непосредственно к логике предметной области, но важная для оптимального функционирования моделей. На данном уровне может проводиться кеширование.

$$$ Слой Модель предметной области

Класс, содержащий бизнес-логику (логику домена). Следуя идее Rich Domain Model, в данном слое должны размещаться классы моделей в соответствии с именованием объектов в предметной области приложения.

$$$ Слой Репозиторий

Группа классов, содержащих инфраструктурную логику - логику поиска, фильтрации и группировки объектов через ORM или через базу данных напрямую.

Слой ORM

Класс, являющийся маппером базы данных и объектной модели. Содержит валидацию уровня базы данных, реляционную (связную) логику. Часто предоставляется фреймворком, может быть на основе паттерна ActiveRecord, пригодного в основном для прототипирования, либо более сложного паттерна DataMapper.

$$$ Безопасность

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

Основные типы уязвимости, которые недопустимы в 99% систем - SQL-инъекции, CSRF-атаки, файловые инъекции (например при загрузке фото), DDOS атаки (в основном требования к серверу), переборы пароля, взлом через "невидимые" файлы (например через папку .svn), подмена токена, MITM-атаки прослушки, XSS-атаки с перегоном трафика на другой сервер. Подробнее про каждую можно почитать в википедии или попросить в комментариях


Развивай навык, формализуй опыт, создавай продукт, автоматизируй труд