Как часть нашего проекта, мы свели вместе информацию об общих подходах к разработке архитектуры приложений. Общие подходы представяют собой набор «горячих точек» (hot spots). Однако это не просто горячие точки. Эти горячие точки преставляют собой ключевые вопросы, проблемы и рекомендации. Все вместе они помогают вырабатывать более эффективные с технической точки зрения архитектуры. Этот список является частью более общей структуры App Arch Meta Frame. Думайте о нём, как о важной ветке большого дерева.
Категории
Следующие категории являются горячими точками в архитектуре приложения:
Аутентификация и авторизация (Authentication and Authorization)
Кэширование и состояние (Caching and State)
Взаимодействие (Communication)
Композиция (Composition)
Параллельные вычисления и транзакции (Concurrency and Transactions)
Управление конфигурацией (Configuration Management)
Связанность и сцепление (Coupling and Cohesion)
Доступ к данным (Data Access)
Работа с исключениями (Exception Management)
Ведение логов и мониторинг (Logging and Instrumentation)
Взаимодействие с пользователем (User Experience)
Проверка данных (Validation)
Поток операций (Workflow)
Горячие точки соответствуют разным сквозным функциональностям, использующимся при создании приложений и, соответственно, разным наборам паттернов и практик. Например, Enterprise Library обычно включает блоки, отвечающие за кэширование, управление исключениями, ведение логов, валидацию и т.д. Категориям также соответствуют разнообразные анти-паттерны, самый плохой из которых — это анти-паттерн «переделать заново» («do over»). :)
Ключевые вопросы
Эта таблица перечисляет ключевые вопросы для каждой горячей точки:
Категория
Ключевые вопросы
Аутентификация и авторизация
Как хранить идентификационные данные зарегистрированных пользователей?
Как аутентифицировать запросы?
Как авторизовывать запросы?
Как передавать идентификационные данные пользователей между слоями приложения?
Кэширование и состояние
Как выбрать эффективную стратегию кэширования?
Как увеличить производительность с помощью кэширования?
Как улучшить безопасность с помощью кэширования?
Как улучшить стабильность с помощью кэширования?
Как поддерживать кэш в актуальном состоянии?
Как определить когда и каким образом использовать специализированный кэш?
Как определить какие данные кэшировать?
Как определить куда кэшировать данные?
Как определить правила удаления данных из кэша из-за устаревания или переполнения?
Как загружать данные кэша?
Как следить за кэшем?
Как синхронизовать между собой множественные кэши?
Как определить какой способ кэширования даёт наибольшую производительность и масштабируемость для определённого сценария и конфигурации.
Как определить какая технология кэшировния удовлетворяет требованиям приложения насчёт безопасности, лёгкости управления и мониторинга.
Взаимодействие
Как передавать информацию между слоями приложения?
Как совершать асинхронные операции?
Как передавать секретные данные?
Композиция
Как спроектировать структуру приложения?
Как спроектировать слабую связанность между модулями?
Как работать с зависимостями в слабосвязанном режиме?
Параллельные вычисления и транзакции
(прим. переводчика): Тут автор продублировал предыдущую категорию. Если ошибка будет исправлена в оригинале, то исправлю и перевод.
Управление конфигурацией
Как определить какая информация подлежит конфигурированию?
Как определить где и каким образом сохранять конфигурационную информацию?
Как работать с секретной информацией?
Как работать с конфигурационной информацией в кластере?
Связанность и сцепление
Как разделить функцональности?
Как структурировать приложение?
Как выбрать подходящее разбиение на слои?
Как задать границы между частями системы?
Доступ к данным
Как управлять соединениями БД?
Как управлять исключениями?
Как улучшить производительность?
Как улучшить управляемость?
Как работать с бинарными данными (BLOBs)?
Как использовать пейджинг (paging) для записей?
Как управлять транзакциями?
Работа с исключениями
Как обрабатывать исключения?
Как сохранять информацию об исключениях?
Ведение логов и мониторинг
Как определить какую информацию писать в лог?
Как сделать запись в лог настраиваемой?
Взаимодействие с пользователем
Как повысить эффективность выполнения задач?
Как улучшить отзывчивость интерфейса?
Как улучшить возможности приложения для пользователя?
Как улучшить внешний вид приложения?
Проверка данных
Как определить где и когда проводить валидацию данных?
Как проверять длину, диапазон, формат и тип данных?
Как ограничить вводимые данные и сообщать о неправильных значениях?
Как обезопасить (sanitize) выводимые данные?
Поток операций
Как решать проблемы параллельных вычислений в потоке операций?
Как обрабатывать ошибки в потоке операций?
Как координировать процессы в потоке операций?
Ключевые проблемы
Эта таблица сводит вместе ключевые проблемы для каждой горячей точки:
Категория
Ключевая проблема
Аутентификация и авторизация
Хранение идентификацонных данных в открытом виде в файлах.
Передача идентификационных данных в открытом виде по сети.
Аккаунты с излишними привилегиями.
Долгоживущие сессии.
Смешивание персонализации и аутентификации.
Использование единственного контроллера доступа (gatekeeper).
Отсутствие ограничений на доступ к системным ресурсам для приложения.
Отсутствие ограничений на доступ к БД кроме определённых хранимых процедур (stored procedures).
Неадекватное разделение прав доступа.
Кэширование и состояние
Промахи кэша.
Отсутствие устаревания (expiration) данных в кэше.
Плохая архитектура кэша.
Отсутствие синхронизации кэша, необходимого для хорошего масштабирования системы.
Взаимодействие
Повышенный сетевой трафик и задержки из-за «тяжёлых» сообщений межу слоями.
Неудачные транспортные протоколы и форматы сообщений.
Слишком большие объёмы данных в сетях ограниченной пропускной способности.
Композиция
Тесно связанные модули
Дублированный код
Параллельные вычисления и транзакции
Блокирующие вызовы.
Негранулированная блокировка данных (nongranular locks).
Неправильная работа с потоками.
Слишком долгое удержание блокировки данных.
Неправильные уровни изоляции БД.
Управление конфигурацией
Небезопасные интерфейсы администрирования.
Небезопасные конфигурационные хранилища.
Хранение конфигурационных данных в открытом виде.
Слишком много администраторов в системе.
Слишком много привилегий для аккаунтов служб и процессов.
Связанность и сцепление
Ограниченная масштабируемость из-за тесной привязанности к серверу и ресурсам.
Смешивание уровней презентации и бизнес-логики, ограничивающее возможни масштабирования.
Проблемы с дальнейшей поддержкой из-за излишней связанности.
Доступ к данным
Использование отдельного логина/пароля для каждого пользователя когда в этом нет необходимости.
«Тяжёлые» запросы к БД.
Рассеянная по классам бизнес-логика.
Работа с исключениями
Оставление системы/приложения в нестабильном состоянии.
Открытие секретной информации конечным пользователям.
Использование исключений для работы логики.
Запись в логи недостаточной информации об исключении.
Ведение логов и мониторинг
Отсутствие логов и мониторинга.
Слишком высокая детализация логов и мониторинга.
Отсутствие настроек логов и мониторинга во время исполнения (run-time).
Отстуствие логов для критических бизнес-операций.
Взаимодействие с пользователем
Неэффективная поддержка задач пользователя.
Плохое время отклика.
Игнорирование пользователей с ограниченными возможностями.
Проверка данных
Фильтрация ошибочных данных лишь на уровне приложения.
Небезопасный вывод данных в HTML.
Небезопасное вставление данных в SQL.
Проверка данных лишь на стороне пользователя.
Использование имён файлов, URLов или имен пользователей для принятия решений насчёт безопасности.
Поток операций
Сильная связанность.
Негибкие процессы.
Проблемы с приоритетами и взаимными блокировками (race and deadlock issues).
Ключевые рекомендации
Эта таблица приводит ключевые рекомендации для каждой горячей точки:
Категория
Ключевые рекомендации
Аутентификация и авторизация
Подумайте над требованиям к регистрации.
Разделите открытые всем и закрытые зоны.
Используйте политики блокировки аккаунтов конечных пользователей (например при множественных ошибках в пароле).
Поддерживайте настраиваемый срок действия пароля.
Обеспечьте возможность отключения (disable) аккаунтов администратором.
Не храните пароли.
Требуйте «сильных» паролей.
Не пересылайте паролей в открытом виде по сети.
Защищайте cookies c идентификационными данными.
Используйте несколько контроллеров доступа (gatekeepers).
Ограничьте доступ пользователей к системным ресурсам.
Подумайте над степенью детализации прав доступа.
Кэширование и состояние
Старайтесь не кэшировать создаваемые лишь для одного пользователя данные.
Не кэшируйте данные, которые должны точно предоставляться пользователю и обновляться в реальном времени.
Кэшируйте данные, которые меняются не очень часто или полностью статичны.
Не кэшируйте очень «тяжёлые» ресурсы.
Кэшируйте данные после преобразований, учитывая актуальность информации, на которой они основаны.
Сравните применимость дизайнов с хранением состояния (stateful) и без такового (stateless).
Обдумайте варианты хранения состояния.
Минимизируйте размер данных в сессии.
Освобождайте ресурсы сессии как можно быстрее.
Старайтесь не запрашивать данные сессии из бизнес-логики.
Взаимодействие
Выберите подходящий механизм удалённого взаимодействия.
Делайте компактные и удобные внешние интерфейсы.
Подумайте над тем, как передавать данные между слоями.
Минимизируйте объём данных, передаваемых по сети.
Используйте пакеты задач (batch work) для уменьшения количества вызовов по сети.
Избегайте транзакций, работающих между границами частей системы.
Обдумайте возможность асинхронного взаимодействия.
Изучите возможность использования очередей сообщений.
Оцените применимость подхода «выстрелил и забыл».
Укорачивайте цепочки обработки вызовов с помощью кэширования. Это улучшит масштабируемость.
Переместите асинхронность ближе к пользователю, интерфейсам служб и служебным агентам для обеспечения изоляции сервиса от внешних зависимостей.
Если вы вынуждены сделать какую-то функциональность синхронной, то подумайте, можно ли внутри сделать асинхронной её часть.
Композиция
Избегайте использования динамических представлений (layouts), которые сложно загружать и поддерживать.
Будьте осторожны с зависимостями между компонентами. Используйте паттерны абстракции при первой возможности для уменьшения потенциальных проблем с поддержкой системы в будущем.
Постарайтесь использовать шаблоны с возможностью вставки данных (placeholders). Например, используйте паттерн Template View для создания динамических веб-страниц, обеспечивающих повторное использование и единообразие.
Расмотрите возможность создания представлений из повторно используемых модулей. Например, используйте паттерн Composite View для создания множества элементарных частей, работающих как готовые модули.
Используйте хорошо известные паттерны для создания составных интерфейсов, содержащих отдельные модули пользовательских контролов.
Модулям не следует прямо ссылаться друг на друга или на приложение, которое их загружает.
Для взаимодействия с другими модулями и самим приложением надо использовать службы.
Модули не должны отвечать за управление своими зависимостями.
Желательно поддерживать добавление и удаление модулей как плагинов.
Параллельные вычисления и транзакции
Относитесь к потоку (thread) как общему ресурсу.
Создавайте пулы общих ресурсов или ресурсов, которых слишком мало.
Запрашивайте ресурс как можно позднее, освобождайте как можно раньше.
Изучите эффективность создания и уничтожения объектов.
Рассмотрите управление пропускной способностью ресурсов.
Снижайте возможные задержки путём минимизации времени блокировки ресурса.
Соблюдайте баланс между высокоуровневыми (coarse) и низкоуровневыми (fine) блокировками.
Выберите подходящий уровень изоляции.
Избегайте выполняющихся долго атомарных транзакций.
Управление конфигурацией
Защищайте интерфейсы администрирования системы.
Защищайте своё конфигурационное хранилище.
Разграничивайте административные полномочия.
Используйте минимально возможноые привилегии для аккаунтов процессов и служб.
Связанность и сцепление
Разбейте приложение на логические слои (layers/tiers).
Правильно выберите расположение для частей приложения в зависимости от требований к надёжности, производительности и масштабируемости.
С самого начала проектируйте систему со слабой связанностью.
Проектируйте систему с сильным сцеплением.
Используйте раннее связывание (early binding) где это возможно.
Оцените сходство ресурсов (resource affinity).
Доступ к данным
Если ваше приложение использует единственную БД, то используйте специализированный провайдер вместо универсального для большего быстродействия.
Если вы поддерживаете несколько видов БД, то вам необходим специальный уровень абстракции, который можно легко настроить под конкретное окружение.
Попробуйте управлять пропускной способностью ресурсов.
Изучите передачу в БД идентификаторов пользователей.
Разделяйте запросы «только для чтения» и транзакционные.
Не возвращайте данные, которые не будут использоваться.
Работа с исключениями
Не показывайте пользователям данные, которые раскрывают внутренности системы.
Не используйте исключения для управления потоком выполнения приложения.
Используйте коды ошибок вместо исключений, где это возможно.
Не перехватывайте исключения, которые вы не можете обработать.
Учтите, что повторное бросание исключения (rethrowing) — дорогая операция.
Сохраняйте как можно больше диагностической информации в ваших обработчиках исключений.
Ведение логов и мониторинг
Постоянно ведите мониторинг.
Сделайте логи настраиваемыми.
Взаимодействие с пользователем
Проверяйте эффективность работы для разных сценариев.
Работайте над улучшением времени отклика системы.
Отталкивайтесь от эффективного дизайна пользовательского интерфейса.
Проверка данных
Проверяйте данные на длину, диапазон, формат и тип.
Ограничивайте вводимые данные и сообщайте об ошибках.
Обезопасьте вводимые данные.
Не полагайтесь на проверку на стороне клиента.
Поток операций
Определите требования к управлению потоками операций. Если ими должен управлять бизнес-пользователь, то обеспечьте ему понятный интерфейс.
Определите как будут обрабатываться исключения в потоке операций.
Когда вы имеете с потоком операций, относящимся к людям, не забывайте о неопределённости человеческой натуры. Нельзя полагаться на то, что какая-то задача будет выполнена в какой-то срок и будет выполнена полностью.
Используйте интерфейсы служб для работы с внешними провайдерами потоков операций.
Используйте визуальные редакторы и метаданные для разаботки потоков операций вместо кода, если это возможно.
От переводчика: Люблю сжатый аналитический подход, поэтому и перевожу. :) И вообще рекомендую блог автора. Там много приятных для мозга списков и таблиц. Разумные поправки к переводу терминов приветствуются. Обсуждение спорных пунктов — тоже.