Проектирование программного обеспечения

Санкт-Петербург, весна 2022

Описание

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

Содержание курса

  1. Архитектура программного обеспечения в целом, роль архитектуры в жизненном цикле программного обеспечения, роль архитектора в команде.
  2. Объектно-ориентированное проектирование, хороший объектно-ориентированный код.
  3. Моделирование, язык UML и, немного, другие визуальные языки.
  4. Шаблоны проектирования (и антипаттерны), архитектурные стили.
  5. Предметно-ориентированное проектирование.
  6. Проектирование распределённых приложений и технологии, с ними связанные.
  7. Развёртывание и немного DevOps.
  8. Примеры архитектур.

Пререквизиты

Аналогичные курсы читаются для студентов 3-го и 4-го курсов в СПбГУ и ВШЭ (так что если вы его уже слушали в своём вузе, записываться на него не стоит). Ожидается владение хотя бы одним объектно-ориентированным языком программирования и некоторый опыт (хоть раз в жизни написали что-то больше 5К строчек — прекрасно). Обязательно умение пользоваться git, очень желательно — писать юнит-тесты. Желательно уметь пользоваться CI и тулами для консольной сборки, но если с этим проблемы — научим.

Преподаватели

Список лекций

Лекция 1: Об архитектуре

Это вводная лекция, в ней кратко рассказывается о том, что будет в курсе, про отчётность и критерии оценивания, а также обсуждается:

  • понятие архитектуры
  • роль архитектуры в жизненном цикле программного обеспечения
  • профессия архитектор и трудовые функции архитектора (что от вас будут ждать на работе)
  • архитектурные стили и архитектурные виды
  • роль моделирования в разработке архитектуры
  • архитектура и эволюция программного обеспечения
Лекция 2: Декомпозиция, объектно-ориентированное проектирование

Эта лекция о:

  • сложности, присущей программным системам, и способах управления ею;
  • декомпозиции, модульности, сопряжении и связности;
  • о том, что такое на самом деле объекты в ООП, к чему абстракция, инкапсуляция, наследование и полиморфизм;
  • как, получив требования, начать строить объектно-ориентированную архитектуру — откуда, собственно, брать объекты, и откуда они иногда сами собой появляются;
  • о принципах SOLID — ключевых принципах хорошего объектно-ориентированного кода.
Практика 2: Объектно-ориентированное проектирование

Практика лекционно-дискуссионного формата, о некоторых тактических соображениях объектно-ориентированного проектирования:

  • интерфейсы абстракций;

  • уровни абстракций;

  • инкапсуляция;

  • о том, что наследование на самом деле — это плохо;

  • соображения, которые надо учитывать при написании конструкторов;

  • про мутабельность;

  • про то, что преждевременная оптимизация очень вредна;

  • про принцип Fail Fast и защитное программирование.

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

Лекция 3: Моделирование, UML

Это лекция — первая в серии о моделировании в архитектуре и языке UML. В ней пойдёт речь о:

  • моделировании вообще;
  • о том, что модели — это не только UML-диаграммы, бывают неформальные или наоборот, формальные модели
  • о том, что такое UML, из каких подъязыков состоит, немного об истории языка
  • подробнее о моделировании статической структуры системы в UML:
    • диаграммы классов;
    • диаграммы пакетов;
    • диаграммы объектов;
    • диаграммы компонентов
Лекция 4: Моделирование и анализ

Эта лекция о:

  • моделировании требований к программному обеспечению:

    • диаграммы случаев использования UML, сценарии использования,
    • диаграммы IDEF0,
    • диаграммы характеристик,
    • диаграммы требований в SysML.
  • моделировании бизнес-процессов, в которые встраивается программное обеспечение:

    • диаграммы активностей UML,
    • диаграммы BPMN;
  • моделировании окружения системы:

    • диаграммы развёртывания UML;
    • моделировании данных системы, моделировании предметной области:
    • диаграммы Сущность-связь
    • ORM-диаграммы.
Лекция 5: Моделирование поведения

Эта лекция — о моделировании поведения системы средствами визуальных языков, заключительная лекция про визуальное моделирование. Будут рассмотрены диаграммы UML: - диаграммы состояний;

  • диаграммы последовательностей;
  • коммуникационные диаграммы;
  • диаграммы составных структур;
  • диаграммы коопераций;
  • временные диаграммы;
  • диаграммы обзора взаимодействия.

И несколько популярных визуальных нотаций помимо UML: - диаграммы потоков данных (DFD);

  • диаграммы IDEF0;
  • сети Петри.
Лекция 6: Структурные шаблоны

Первая лекция из серии о паттернах проектирования. На этой лекции рассмотрим, что такое вообще шаблоны проектирования и зачем они, рассмотрим структурные шаблоны:

  • Компоновщик
  • Декоратор
  • Стратегия
  • Адаптер
  • Заместитель
  • Фасад
  • Приспособленец
Практика 6: Архитектурная документация

Практика в лекционном формате, про архитектурную документацию. Рассмотрим, зачем и как её писать, стандарты на архитектурное описание: IEEE 42010:2011 и IEEE 1016-2009 (как пример того, что в принципе можно там писать и как документ должен быть структурирован). На дом будет задание написать архитектурную документацию к относительно большой системе (которую сначала надо будет спроектировать), так что слушать/читать конспект рекомендуется внимательно.

Лекция 7: Порождающие шаблоны

Продолжение рассказа про основные паттерны объектно-ориентированного проектирования. Будет рассмотрен оставшийся структурный паттерн Мост (достаточно важный, чтобы ради него стоило нарушать принцип единственности ответственности в содержании лекции) и порождающие паттерны:

  • Фабричный метод;

  • Абстрактная фабрика;

  • Одиночка;

  • Прототип.

И два неканоничных паттерна, которых нет в книжке Гаммы et al.: Ленивая инициализация и Пул объектов.

Практика 7: Примеры архитектур

Очередная практика в лекционном формате, рассказ про некоторые примеры архитектур:

  • Enterprise Fizz-Buzz (шуточный проект, но прекрасный пример овердизайна)
  • Bash (интересен в контексте прошлых домашних заданий)
  • Battle for Wesnoth (интересен в контексте текущих домашних заданий)
Лекция 8: Поведенческие шаблоны

Эта лекция завершает обзор паттернов проектирования рассмотрением поведенческих паттернов:

  • Строитель;
  • Шаблонный метод;
  • Посредник;
  • Команда;
  • Цепочка ответственности;
  • Наблюдатель;
  • Состояние;
  • Посетитель;
  • Хранитель;
  • Интерпретатор;
  • Итератор.
Практика 8: Антипаттерны

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

антипаттерны реализации:

  • Круговая зависимость;
  • Последовательная зависимость;
  • Вызов предка;
  • Проблема йо-йо;
  • Активное ожидание;
  • Сокрытие ошибок;
  • Магические числа;
  • Магические строки;

антипаттерны проектирования:

  • Божественный объект;
  • Швейцарский нож;
  • Поток лавы;
  • Функциональная декомпозиция;
  • Золотой молоток;

антипаттерны архитектуры: - Зависимость от поставщика;

  • Неявная архитектура;
  • Проектирование комитетом.
Лекция 9: Архитектурные стили

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

  • то, что такое архитектурные шаблоны и стили вообще;
  • примеры архитектурных шаблонов: трёхзвенная архитектура, Model-View-Controller, Sense-Compute-Control;
  • примеры архитектурных стилей, включая:
    • сырой объектно-ориентированный стиль (и что на самом деле парадигма программирования обычно подразумевает и стиль архитектуры, хоть и слабо выраженный);
    • слоистый стиль и его подвиды: чистый слоистый стиль, клиент-сервер;
    • тоже на самом деле подвиды слоистого стиля, но более модные: гексагональная архитектура, луковая архитектура, чистая архитектура;
    • стили, ориентированные на потоки данных: пакетная обработка, Pipes and Filters;
    • стиль Blackboard;
    • событийные стили и их подвиды: publish-subscribe, шины данных;
    • стиль Peer-to-peer.
Лекция 10: Предметно-ориентированное проектирование

Эта лекция об очень популярной нынче методологии проектирования объектно-ориентированных систем — предметно-ориентированном проектировании (Domain-Driven Design, DDD). Будут рассмотрены ключевые принципы предметно-ориентированного моделирования:

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

Также будут рассмотрены основные структурные элементы модели предметной области по DDD:

  • сущность;

  • объект-значение;

  • служба;

  • модуль.

И основные паттерны проектирования модели:

  • Агрегат;
  • Фабрика;
  • Репозиторий;
  • Спецификация.

DDD можно рассматривать как пример методологии, построенной вокруг слоистого и объектно-ориентированного стилей.

Книга, по сути кратким пересказом первой части которой является эта лекция: Эрик Эванс, Предметно-ориентированное проектирование. Структуризация сложных программных систем. М., Вильямс, 2010, 448 стр. Must read если не для каждого программиста, то для каждого, кто претендует на позицию архитектора в будущем.

Практика 10: Примеры архитектур

Ещё одна лекция с примерами архитектур приложений с открытым исходным кодом. На сей раз систем контроля версий:

  • Git;
  • Mercurial;
  • Subversion.

Рассмотрим ключевые требования, высокоуровневую архитектуру, представление данных у трёх систем, решающих по сути одну задачу.

Лекция 11: Проектирование распределённых приложений, часть первая: технические вопросы

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

  • Remote Procedure Calls (RPC), Remote Method Invocation (RMI);
  • пример конкретной технологии: protobuf/gRPC.

  • веб-сервисы:

    • SOAP-ориентированные сервисы и фреймворк WCF как пример;
    • REST-сервисы и ASP.NET Web APIs как пример;
  • очереди сообщений и два примера: RabbitMQ и Apache Kafka.

Лекция 12: Проектирование распределённых приложений, часть вторая: архитектурные вопросы

Эта лекция продолжает предыдущую обсуждением общих вопросов проектирования больших распределённых приложений. Рассмотрим:

Архитектурные стили распределённых систем:

  • Big Compute;
  • Big Data;
  • Событийная шина;
  • Web-queue-worker;
  • N-звенная архитектура;
  • Микросервисная архитектура.

Обсудим также прагматические соображения проектирования

  • Идеологически правильный дизайн REST API;
  • Механизмы самовосстановления и устойчивости к ошибкам;
  • Вопросы координации компонентов;
  • Проектирование для обслуживания.
Практика 12: Развёртывание

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

  • Docker и Docker Compose;
  • Kubernetes;
  • Облачная инфраструктура на примере AWS;
  • Infrastructure as Code.