├── Data-types.md ├── README.md ├── api-security.md ├── docker-roadmap.md ├── inheritanceVsCompositionVsAggregation.md ├── interfaces.md ├── lastStaticBindings.md ├── singleton.md ├── software-design-and-architecture.md ├── static-methods-and-properties.md └── system-design.md /Data-types.md: -------------------------------------------------------------------------------- 1 | # Типы данных 2 | 3 | В таблице перечислены типы данных, используемые в PHP, а также соответствующие им функции проверки [http://php.net/manual/ru/language.types.intro.php](http://php.net/manual/ru/language.types.intro.php). 4 | 5 | | Фукнция проверки | Тип | Описание | 6 | | ----------------- | ------------- | -------------- | 7 | | is_bool() | Boolean | Одно из двух значений: true или false (истина или ложь). Скалярный тип данных | 8 | | is_integer(), is_int(), is_long() | Integer | Целое число. Скалярный тип данных | 9 | | is_double(), is_float() | Double | Число с плавающей точкой. Скалярный тип данных | 10 | | is_string() | String | Символьные данные. Скалярный тип данных | 11 | | is_array() | Array | Массив. Смешанный тип данных | 12 | | is_object() | Object | Объект. Смешанный тип данных | 13 | | is_callable() | Callable | Функции обратного вызова (callback-функции). Смешанный тип данных | 14 | | is_iterable() | Iterable | Псевдотип, введенный в PHP 7.1. Он принимает любой массив или объект, реализующий интерфейс Traversable. Смешанный тип данных | 15 | | is_resource() | Resource | Дескриптор, используемый для идентификации и работы с внешними ресурсами, такими как базы данных, файлы, области изображения. Специальных тип данных | 16 | | is_null() | Null | Неинициализированное значение. Специальных тип данных | 17 | 18 | Кроме того, существуют псевдотипы - слова, используемые в документации PHP, для обозначения типов или значений, какие могут принимать аргументы. К ним относятся [https://www.php.net/manual/ru/language.pseudo-types.php](https://www.php.net/manual/ru/language.pseudo-types.php) 19 | - [mixed](https://www.php.net/manual/ru/language.pseudo-types.php#language.types.mixed) 20 | - [number](https://www.php.net/manual/ru/language.pseudo-types.php#language.types.number) 21 | - [callback (callable)](https://www.php.net/manual/ru/language.pseudo-types.php#language.types.callback) 22 | - [array|object](https://www.php.net/manual/ru/language.pseudo-types.php#language.types.array-object) 23 | - [void](https://www.php.net/manual/ru/language.pseudo-types.php#language.types.void) 24 | и псевдопеременная [$...](https://www.php.net/manual/ru/language.pseudo-types.php#language.types.dotdotdot). 25 | -------------------------------------------------------------------------------- /api-security.md: -------------------------------------------------------------------------------- 1 | [Оригинал](https://roadmap.sh/best-practices/api-security) 2 | 3 | # Рекомендации по защите API 4 | 5 | Перечень рекомендаций по защите API с пояснениями 6 | 7 | ## Аутентификация 8 | 9 | ### Избегайте «базовой аутентификации» ('Basic Authentication'), используйте стандарты (например, JWT) 10 | 11 | > Cледует избегать использования «базовой аутентификации» и использовать любые другие стандартные методы аутентификации, например OAuth, JWT и т. д. 12 | 13 | Базовая аутентификация – это простой метод аутентификации пользователя путем передачи учетных данных пользователя в виде обычного текста по сети. Этот метод по своей сути небезопасен, и его следует избегать, когда это возможно. 14 | 15 | Существует несколько причин, по которым следует избегать базовой аутентификации и заменять ее более безопасными методами аутентификации: 16 | 17 | * Отсутствие конфиденциальности: базовая аутентификация передает учетные данные пользователя (имя пользователя и пароль) в виде обычного текста по сети. Это означает, что любой, кто перехватывает трафик, может легко считать учетные данные и получить доступ к учетной записи пользователя. 18 | 19 | * Отсутствие целостности: базовая аутентификация не обеспечивает какого-либо механизма, гарантирующего, что передаваемые данные не были подделаны или изменены при передаче. Это означает, что злоумышленник может изменить трафик, чтобы получить доступ к учетной записи пользователя или выполнить другие вредоносные действия. 20 | 21 | * Недостаточная надежность аутентификации: базовая аутентификация полагается исключительно на учетные данные пользователя для их аутентификации. Это означает, что если злоумышленнику удастся получить учетные данные пользователя (например, с помощью фишинга или социальной инженерии), он сможет легко получить доступ к учетной записи пользователя. 22 | 23 | * Нет поддержки многофакторной аутентификации: базовая аутентификация не поддерживает многофакторную аутентификацию (MFA), которая является важным элементом безопасности и обеспечивает дополнительный уровень защиты от несанкционированного доступа. 24 | 25 | И наоборот, другие методы аутентификации, такие как OAuth, OpenID Connect и SAML, предоставляют более безопасные и надежные методы аутентификации. Эти методы обычно используют зашифрованные протоколы для защиты учетных данных пользователя, предоставляют механизмы проверки целостности данных и поддерживают MFA. В результате они гораздо более безопасны и надежны, чем базовая аутентификация, и их следует использовать всегда, когда это возможно. 26 | 27 | ### Не изобретайте велосипед в механизмах аутентификации 28 | 29 | > Используйте стандартные механизмы аутентификации для создания токенов, хранения учетных данных и аутентификации пользователей 30 | 31 | Вот несколько примеров устоявшихся механизмов аутентификации, которые вы можете использовать вместо того, чтобы изобретать велосипед: 32 | 33 | * OAuth: OAuth – это широко используемый открытый стандарт авторизации, который позволяет пользователям предоставлять сторонним приложениям доступ к своим ресурсам, не передавая свои учетные данные. Он обычно используется веб-службами и API, чтобы пользователи могли входить в систему, используя свои учетные записи в социальных сетях или другие сторонние учетные записи. 34 | 35 | * OpenID Connect: OpenID Connect – это протокол аутентификации, созданный на основе OAuth 2.0, который позволяет пользователям проходить аутентификацию на нескольких веб-сайтах и в приложениях, используя один набор учетных данных. Он обычно используется для единого входа (SSO) на нескольких веб-сайтах и в приложениях. 36 | 37 | * SAML: **S**ecurity **A**ssertion **M**arkup **L**anguage (SAML, язык разметки декларации безопасности) – это стандарт на основе XML для обмена данными аутентификации и авторизации между сторонами. Он обычно используется для единого входа в нескольких доменах или организациях. 38 | 39 | * Алгоритмы хеширования паролей: алгоритмы хеширования паролей, такие как `bcrypt` и `scrypt`, широко используются для безопасного хранения и защиты паролей пользователей. Эти алгоритмы гарантируют, что даже если злоумышленник получит доступ к базе данных паролей, он не сможет легко восстановить пароли. 40 | 41 | * Двухфакторная аутентификация (2FA): 2FA – это механизм аутентификации, который требует от пользователей предоставления двух форм идентификации для доступа к своим учетным записям. Обычно это включает в себя что-то, что знает пользователь (например, пароль) и что-то, что у него есть (например, мобильное устройство или ключ безопасности). Многие сервисы и приложения теперь предлагают 2FA в качестве дополнительной меры безопасности. 42 | 43 | ### Используйте максимальное число неудачных попыток ('Max Retry') и функционал, осуществляющий блокировку, при определённом числе неудачных входов в систему 44 | 45 | > Максимальное число неудачных попыток и блокировка часто используются в механизмах входа в систему для повышения безопасности и предотвращения атак методом «грубой силой» 46 | 47 | **Максимальное число неудачных попыток**: Функционал «максимальное число неудачных попыток» ограничивает количество попыток входа в систему, которые пользователь может сделать в течение определенного периода времени. После определенного количества неудачных попыток входа в систему блокируется учетная запись пользователя на определенный период времени, обычно на несколько минут или часов. Это помогает предотвратить атаки методом «грубой силой», когда злоумышленник пытается угадать пароль пользователя, предпринимая повторные попытки входа в систему. Ограничивая количество попыток, система может замедлить или предотвратить такие атаки. 48 | 49 | **Блокировка**: Функционал «блокировки» предполагает блокировку IP-адресов или учетных записей пользователей, у которых превышено максимальное количество неудачных попыток входа в систему в течение определенного периода времени. Заблокированным IP-адресам или учетным записям пользователей запрещается дальнейший вход в систему в течение определенного периода времени, обычно нескольких минут или часов. Это помогает предотвратить атаки методом «грубой силой», а также обеспечивает механизм, предотвращающий повторные попытки злоумышленников получить доступ к учетной записи или системе. 50 | 51 | ### Используйте шифрование для всех конфиденциальных данных 52 | 53 | > Шифрование конфиденциальных данных важно для их защиты от несанкционированного доступа, кражи и использования 54 | 55 | Шифрование – это процесс преобразования простых текстовых данных в зашифрованный текст, который может быть расшифрован только тем, у кого есть ключ дешифрования. Это затрудняет злоумышленникам доступ к конфиденциальным данным, даже если они могут их перехватить или получить к ним несанкционированный доступ. 56 | 57 | Для шифрования конфиденциальных данных вы можете использовать такие алгоритмы шифрования, как `AES` или `RSA`, а также надежную систему управления ключами, обеспечивающую безопасное хранение и управление ключами. Кроме того, вы можете реализовать другие меры безопасности, такие как контроль доступа, брандмауэры и системы обнаружения хакерских атак, для дальнейшей защиты конфиденциальных данных. 58 | 59 | ## JWT (JSON веб-токен) 60 | 61 | ### Используйте такой «JWT секретный ключ» ('JWT Secret'), который усложнит его подбор атакой методом «грубой силой» (полным перебором) 62 | 63 | > Позаботьтесь о хорошем секретный ключе для JWT для защиты от внесения злонамеренных изменений в токен (подделки токена), а также для предотвращения атак методом «грубой силы» 64 | 65 | Надёжный секретный ключ должен генерироваться случайным образом, быть длинным и сложным, храниться в надежном месте и периодически меняться. 66 | 67 | ### Не извлекайте алгоритм из заголовка запроса, используйте бэкенд 68 | 69 | > Не извлекайте алгоритм из заголовка запроса, используйте бэкенд 70 | 71 | Извлечение алгоритма из заголовка JWT токена может представлять угрозу безопасности, поскольку злоумышленник может изменить алгоритм и потенциально получить несанкционированный доступ. Поэтому рекомендуется проверять алгоритм, используя бэкенд, а не извлекать его из заголовка. Это поможет гарантировать, что алгоритм, используемый для подписи и проверки токена, безопасен и не был подделан. 72 | 73 | ### Делайте срок действия токена (TTL, RTTL) как можно короче 74 | 75 | > Срок действия токена должен быть выбран в соответствии с требованиями к системе и не превышать объективно необходимый срок, чтобы уменьшить окно уязвимости системы, ограничить 76 | > последствия кражи токенов и повысить общую безопасность 77 | 78 | Установка короткого срока действия токена (TTL, RTTL) важна в целях безопасности, поскольку уменьшает окно уязвимости, ограничивает влияние кражи токена и повышает общую безопасность. Однако срок действия должен быть сбалансирован с удобством использования, поскольку слишком короткий срок может доставить неудобства пользователям и снизить производительность. 79 | 80 | ### Избегайте хранения конфиденциальных данных в полезной нагрузке JWT 81 | 82 | > Избегайте хранения конфиденциальных данных в полезной нагрузке JWT 83 | 84 | Хранение конфиденциальных данных в полезной нагрузке JWT токена может увеличить риск утечки данных и других ситуаций, связанных с нарушением безопасности. Если злоумышленник сможет раздобыть или подделать токен, он потенциально может получить доступ к конфиденциальным данным, хранящимся в полезных данных. 85 | 86 | ### Старайтесь сделать полезную нагрузку небольшой, чтобы уменьшить размер JWT токена 87 | 88 | > Избегайте хранения больших полезных нагрузок в JWT токенах 89 | 90 | Небольшая полезная нагрузка может снизить накладные расходы при передаче по сети, повысить скорость обработки и снизить риск атак, направленных на перегрузку системы. 91 | 92 | ## Контроль доступа 93 | 94 | ### Ограничивайте число запросов (ограничение пропускной способности, throttling), чтобы избежать DDoS атак / атакой методом «грубой силой» 95 | 96 | > Ограничивайте число запросов (ограничение пропускной способности, throttling), чтобы избежать DDoS атак / атакой методом «грубой силой» 97 | 98 | Ограничение числа запросов посредством регулирования пропускной способности важно для предотвращения DDoS-атак и атак методом «грубой силой». DDoS-атаки перегружают сервер слишком большим количеством запросов, в то время как атаки методом «грубой силы» пытаются угадать учетные данные пользователя посредством нескольких попыток входа в систему. 99 | 100 | Регулировка пропускной способности ограничивает количество запросов, которые могут быть отправлены в течение определенного периода времени, что усложняет злоумышленникам проведение атак такого типа. Это может защитить систему от перегрузки и предотвратить несанкционированный доступ злоумышленников. 101 | 102 | ### Используйте HTTPS на стороне сервера и безопасные алгоритмы шифрования 103 | 104 | > Используйте HTTPS на стороне сервера и безопасные алгоритмы шифрования 105 | 106 | Убедитесь, что ваш API сервер использует HTTPS вместо HTTP. HTTPS – это безопасный протокол, который шифрует данные при передаче, что затрудняет перехват и чтение конфиденциальной информации злоумышленниками. Чтобы реализовать HTTPS, вам необходимо получить сертификат SSL/TLS и настроить сервер на использование HTTPS. 107 | 108 | HTTPS использует шифры для шифрования данных при передаче. Важно выбирать безопасные шифры, устойчивые к атакам и обеспечивающие надежное шифрование. Примерами чаще всего используемых безопасных шифров для обмена ключами являются AES, ChaCha20 и ECDHE. Обязательно отключите слабые и устаревшие алгоритмы шифрования, такие как RC4 и TLS 1.0/1.1, которые уязвимы для атак. 109 | 110 | ### Используйте заголовок HSTS с SSL, чтобы избежать атак SSL Strip 111 | 112 | > Используйте заголовок HSTS с SSL, чтобы избежать атак SSL Strip 113 | 114 | SSL Strip – это тип атаки, когда злоумышленник перехватывает трафик между клиентом и сервером, который должен быть защищен с помощью SSL/TLS-шифрования, и понижает уровень соединения до простого текстового (незашифрованного) HTTP-соединения. Этот тип атаки может остаться незамеченным пользователем, поскольку злоумышленник может перенаправить пользователя на похожий веб-сайт, который также использует HTTP вместо HTTPS. 115 | 116 | При SSL Strip атаке злоумышленник является «человеком посередине» (MITM) между клиентом и сервером. Когда клиент инициирует соединение с сервером, злоумышленник перехватывает SSL/TLS трафик и удаляет или заменяет HTTPS ссылки HTTP ссылками. Это может заставить пользователя думать, что он использует безопасное соединение, хотя на самом деле это не так. Затем злоумышленник может отслеживать и манипулировать данными, передаваемыми между клиентом и сервером. 117 | 118 | HSTS заголовок – это заголовок безопасности, который указывает браузерам получать доступ к сайту только через HTTPS. Этот заголовок используется для предотвращения SSL Strip атак. Рекомендуется использовать заголовок HSTS с SSL. 119 | 120 | ### Отключите вывод содержимого каталогов 121 | 122 | > Отключите вывод содержимого каталогов 123 | 124 | Вывод содержимого каталогов – это функция веб-серверов, которая позволяет пользователям просматривать содержимое каталога на сервере. По умолчанию на веб-серверах часто включен вывод содержимого каталогов, а это означает, что любой, у кого есть доступ к серверу, может видеть все файлы и каталоги в данной папке. 125 | 126 | Отключение вывода содержимого каталогов важно для безопасности API, поскольку оно не позволяет злоумышленникам получить доступ к конфиденциальным файлам и каталогам на сервере. Если вывод содержимого каталогов включен и злоумышленник получает доступ к серверу, он может легко просмотреть и загрузить любые файлы, которые не защищены должным образом. Отключив вывод содержимого каталогов, вы можете гарантировать, что только авторизованные пользователи смогут получить доступ к файлам и каталогам на сервере. 127 | 128 | ### Приватные API должны быть доступны только для «безопасного» списка IP-адресов 129 | 130 | > Приватные API должны быть доступны только для «безопасного» списка IP-адресов 131 | 132 | Приватные API должны быть доступны только с IP-адресов, включенных в «безопасный» список, чтобы гарантировать, что только авторизованные пользователи или системы могут получить доступ к API. Предоставляя доступ только с определенных IP-адресов, вы можете предотвратить несанкционированный доступ из внешних сетей или злоумышленников. Это может помочь защитить конфиденциальные данные и предотвратить такие атаки, как DDoS или атаки методом «грубой силой». Кроме того, предоставление доступа только IP-адресам из «безопасного» списка может помочь обеспечить надежность и производительность API, предотвращая чрезмерный трафик из неавторизованных источников. 133 | 134 | ## OAuth 135 | 136 | ### Всегда проверяйте 'redirect_uri' на стороне сервера 137 | 138 | > Проверяйте 'redirect_uri' на стороне сервера чтобы предотвратить Open Redirect атаки 139 | 140 | В OAuth `redirect_uri` – это параметр, указывающий URI (унифицированный идентификатор ресурса), на который сервер авторизации должен перенаправить пользователя после завершения аутентификации. `Redirect_uri` часто используется в потоке OAuth для возврата кода авторизации или токена доступа клиентскому приложению. 141 | 142 | Важно проверять `redirect_uri` на стороне сервера, чтобы предотвратить такие атаки, как Open Redirect атаки. При Open Redirect атаке злоумышленник может изменить параметр `redirect_uri`, чтобы перенаправить пользователя на вредоносный веб-сайт. Проверив `redirect_uri` на стороне сервера, вы можете убедиться, что URI перенаправления является правильным и авторизованным URI для клиентского приложения. 143 | 144 | Проверка `redirect_uri` на стороне сервера также может предотвратить другие типы атак, такие как фишинговые атаки или атаки с подделкой межсайтовых запросов (CSRF). Проверив, что `redirect_uri` соответствует заранее определенному списку авторизованных URI, вы можете гарантировать, что пользователь будет перенаправлен на сайт, которому можно доверять, после завершения аутентификации. 145 | 146 | ### Не используйте 'response_type=token', а вместо него применяйте поток с кодом подтверждения 147 | 148 | > Не используйте 'response_type=token', а вместо него применяйте поток с кодом подтверждения 149 | 150 | В OAuth `response_type=token` – это метод получения токена доступа непосредственно из конечной точки авторизации без использования кода авторизации. Этот метод известен как *Implicit Grant Flow* (поток неявного доступа). 151 | 152 | Однако рекомендуется избегать использования `response_type=token` и вместо этого использовать *Authorization Code Grant Flow* (поток с кодом подтверждения), при котором клиент обменивает код авторизации на токен доступа. Это связано с тем, что поток неявного доступа может быть менее безопасным, чем поток с кодом подтверждения. 153 | 154 | Причина этого в том, что токен доступа возвращается непосредственно клиенту во фрагменте URL-адреса URI, который используется для редиректа. Это означает, что токен доступа может быть перехвачен или обнаружен в истории браузера или журналах сервера. Напротив, в потоке с кодом подтверждения токен доступа возвращается клиенту только после того, как клиент обменял код авторизации на токен, используя безопасную связь между серверами. 155 | 156 | Таким образом, используя поток с кодом подтверждения вместо потока неявного доступа, вы можете защитить токен доступа от обнаружения или перехвата злоумышленниками. 157 | 158 | ### Используйте параметр 'state' для предотвращения CSRF атак 159 | 160 | > Используйте параметр 'state' для предотвращения CSRF атак 161 | 162 | В OAuth параметр `state` используется в качестве меры безопасности для предотвращения CSRF атак (подделка межсайтовых запросов). CSRF атаки возникают, когда вредоносный веб-сайт или сценарий отправляет запрос на настоящий веб-сайт от имени пользователя, который на момент отправки уже авторизирован на нём. 163 | 164 | Чтобы предотвратить CSRF атаки, используется параметр `state` для хранения уникального значения, которое генерируется клиентским приложением перед инициированием запроса на авторизацию. Это значение добавляется в запрос авторизации, а затем проверяется сервером авторизации, когда пользователь перенаправляется обратно в клиентское приложение. Если значение `state` в ответе на авторизацию совпадает со значением `state`, отправленным клиентским приложением, авторизация считается действительной, и токен доступа возвращается клиенту. 165 | 166 | Используя параметр `state`, вы можете предотвратить перехват или изменение запроса на авторизацию злоумышленниками при передаче, поскольку уникальное значение `state` известно только клиентскому приложению и серверу авторизации. Это может обеспечить целостность и безопасность OAuth потока и защитить от CSRF атак. 167 | 168 | ### У вас должен быть «набор запрашиваемых у пользователя разрешений на доступ к данным» (scope) по умолчанию и необходимо проверять его для каждого приложения 169 | 170 | > У вас должен быть scope по умолчанию и необходимо проверять его для каждого приложения 171 | 172 | В OAuth scopes используются для определения набора разрешений и уровней доступа, которые предоставляются клиентским приложениям при доступе к защищенным ресурсам от имени пользователя. 173 | 174 | Лучшей практикой является использование scope по умолчанию, а также проверка его для каждого приложения, поскольку это помогает гарантировать, что клиентские приложения имеют доступ только к тем ресурсам, которые им необходимы, и что пользователи предоставляют только необходимые разрешения каждому приложению. 175 | 176 | Scope по умолчанию – это набор разрешений, которые предоставляются всем клиентским приложениям по умолчанию, если иное не указано пользователем. Имея scope по умолчанию, вы можете гарантировать, что ко всем приложениям применяются одинаковые базовые параметры безопасности и контроля доступа. 177 | 178 | Помимо наличия scope по умолчанию, также рекомендуется проверять scope для каждого приложения. Это означает, что когда пользователь предоставляет доступ к приложению, сервер должен проверить, является ли запрошенный scope допустимым и подходящим для этого приложения. Это может помочь предотвратить запрос вредоносными приложениями чрезмерных разрешений или несанкционированный доступ к пользовательским данным. 179 | 180 | Имея scope по умолчанию и проверяя scope для каждого приложения, вы можете гарантировать, что OAuth поток безопасен и что клиентские приложения получают доступ только к тем ресурсам и разрешениям, которые им необходимы. 181 | 182 | ## Обработка 183 | 184 | ### Проверьте для всех ли конечных точек с доступом только для аутентифицированных пользователей выполняется процесс аутентификации, чтобы избежать нарушения процесса аутентификации 185 | 186 | > Проверьте для всех ли конечных точек с доступом только для аутентифицированных пользователей выполняется процесс аутентификации, чтобы избежать нарушения процесса аутентификации 187 | 188 | Выявляя и исправляя нарушененные процессы аутентификации, API может предотвратить такие атаки, как методом «грубой силы», подстановки учетных данных, перехвата сеанса и другие атаки, связанные с аутентификацией. Это поможет обеспечить безопасность системы и защиту конфиденциальных данных. 189 | 190 | ### Избегайте использования идентификатора пользователя в URL-адресах ресурсов, например, `users/242/orders` 191 | 192 | > Избегайте использования идентификатора пользователя в URL-адресах ресурсов, например, `users/242/orders` 193 | 194 | Следует избегать использования собственного идентификатора пользователя. Используйте `/me/orders` вместо `/user/654321/orders`. Это поможет избежать риска раскрытия личного идентификатора пользователя, который может быть использован для дальнейших атак. 195 | 196 | ### Предпочитайте использовать UUID вместо автоинкрементных идентификаторов 197 | 198 | > Используйте UUID вместо целых чисел с автоматическим инкрементом. UUID глобально уникальны и не являются последовательными. Их также сложнее угадать, чем последовательные целые числа 199 | 200 | Использование UUID вместо автоинкрементных идентификаторов не позволяет злоумышленникам угадывать или перебирать идентификаторы ресурсов. UUID генерируются случайным образом и содержат 128 бит энтропии, поэтому злоумышленникам практически невозможно их угадать. Напротив, значения автоинкрементных идентификаторов можно легко предсказать или вычислить, что позволяет злоумышленникам получить доступ или манипулировать ресурсами, к которым у них не должно быть доступа. Кроме того, использование UUID может помочь предотвратить утечку информации, скрывая порядок создания ресурсов или доступа к ним. 201 | 202 | ### Отключите парсинг поступающих извне XML сущностей, если вы парсите XML, чтобы избежать XXE атак 203 | 204 | > Отключите парсинг поступающих извне XML сущностей, если вы парсите XML, чтобы избежать XXE атак 205 | 206 | Если XML парсер уязвим для XXE атак, злоумышленник может использовать эту уязвимость для чтения файлов на сервере, выполнения SSRF атак и многого другого. Это может привести к раскрытию конфиденциальной информации, отказу в обслуживании и другим атакам. 207 | 208 | XXE атака (XML External Entity, инъекция внешних сущностей XML) – это тип атаки, нацеленной на приложения, которые анализируют XML, поступающие из ненадежных источников. В ходе этой атаки злоумышленник внедряет вредоносное XML данные. Они могут содержать внешние объекты, которые злоумышленник может использовать для получения конфиденциальных данных, выполнения удаленного кода или запуска атак типа «отказ в обслуживании». XXE атаки можно предотвратить, отключив обработку внешних сущностей или проверив и очистив входные данные XML перед их анализом. 209 | 210 | ### Отключите расширения, позволяющие обрабатывать поступающие извне сущности, если вы используете XML, YML или любой другой язык 211 | 212 | > Отключите расширения, позволяющие обрабатывать поступающие извне сущности, если вы используете XML, YML или любой другой язык 213 | 214 | Отключение расширений, позволяющих обрабатывать поступающие извне сущности, важно при использовании XML, YAML или любого другого языка, который разрешает сущности, поскольку это помогает предотвратить XXE атаки (XML External Entity, инъекция внешних сущностей XML) или внедрение YAML тегов. В ходе этих атак злоумышленник обычно вставляет во входные данные какой-то собственный код для выполнения атак на приложение. Отключив расширение для работы с сущностями, входными данными нельзя манипулировать таким образом, что снижает риск этих атак. 215 | 216 | ### Используйте CDN для загрузки файлов 217 | 218 | > Используйте CDN для загрузки файлов 219 | 220 | Использование Content Delivery Network (CDN, сети доставки содержимого) для загрузки файлов может сделать API более безопасным, разгружая трафик загрузки файлов с API сервера и снижая риск DDoS-атак. 221 | 222 | ### Избегайте ситуаций, когда часть HTTP запросов не может быть обработана из-за большого объёма данных 223 | 224 | > Избегайте ситуаций, когда часть HTTP запросов не может быть обработана из-за большого объёма данных, перенеся тяжелые HTTP операции в фоновые или асинхронные задачи 225 | 226 | Невозможность обработки HTTP запросов – распространенная проблема в веб-приложениях. Она возникает, когда приложение не может обрабатывать входящие HTTP-запросы из-за большого количества запросов или большого объёма данных. Это может привести к тому, что приложение перестанет отвечать на запросы и произойдёт сбой сервера. Этого можно избежать, переместив тяжелые HTTP операции в фоновые или асинхронные задачи. Вы можете использовать очередь сообщений для постановки запросов в очередь и обработки их в фоновом режиме. Это позволит приложению продолжать обработку других запросов, пока тяжелые операции выполняются в фоновом режиме. 227 | 228 | ### Обязательно отключите режим отладки на продакшене 229 | 230 | > Убедитесь, что режим отладки отключён на продакшене 231 | 232 | Режим отладки – это функционал, который помогает разработчикам отлаживать свой код. Он не предназначен для использования в продакшене. Он может раскрыть конфиденциальную информацию о приложении и сервере, на котором работает. Обязательно отключите режим отладки в продакшене. 233 | 234 | ### Используйте Non-Executable Stacks, когда это возможно 235 | 236 | > Используйте Non-Executable Stacks, чтобы не дать злоумышленникам выполнить код на вашем сервере 237 | 238 | Под стеком обычно понимают стеку вызовов или стек выполнения. Это структура данных, используемая компьютерной программой для управления и отслеживания последовательности вызовов функций, локальных переменных и других связанных данных во время выполнения программы. 239 | 240 | Non-Executable Stack (неисполняемый стек) — это механизм обеспечения защиты, который предотвращает выполнение вредоносного кода, не давая выполняться памяти стека как код. Это помогает предотвратить такие атаки, как атаки на переполнение буфера, когда злоумышленник пытается перезаписать адрес возврата в стеке, чтобы перенаправить программу на выполнение вредоносного кода. Используя Non-Executable Stacks, программа может хранить стек отдельно от исполняемого кода и помогать предотвращать атаки такого типа. 241 | 242 | ## Обработка входных данных 243 | 244 | ### Используйте HTTP-метод, соответствующий осуществляемой операции 245 | 246 | Используйте HTTP-метод, соответствующий осуществляемой операции: `GET` (для чтения), `POST` (для создания), `PUT/PATCH` (для замены/обновления) и `DELETE` (для удаления записи) и отвечайте кодом `405 Method Not Allowed`, если какой-то метод нельзя использовать для запрошенного ресурса. 247 | 248 | ### Проверяйте заголовок `Content-type` в запросе 249 | 250 | > Проверяйте заголовок `Content-type` в запросе, чтобы предотвратить XSS-атаки 251 | 252 | Проверка заголовка `Content-Type` в запросе может повысить безопасность API, гарантируя, что данные запроса имеют ожидаемый формат, и снижая риск атак, таких как инъекционная атака или межсайтовый скриптинг (XSS). 253 | 254 | ### Проверяйте вводимые пользователем данные, чтобы избежать распространенных уязвимостей 255 | 256 | > Проверяйте вводимые пользователем данные, чтобы избежать распространенных уязвимостей 257 | 258 | Вводимые пользователем данные являются распространенным источником уязвимостей в веб-приложениях. Это связано с тем, что вводимые пользователем данные часто не проверяются, не очищаются и не экранируются должным образом перед использованием в веб-приложении. Это может позволить злоумышленнику манипулировать входными данными и выполнить вредоносный код или вызвать неожиданное поведение приложения. 259 | 260 | ### Используйте стандартный заголовок `Authorization` для конфиденциальных данных 261 | 262 | > Используйте стандартный заголовок `Authorization` для отправки токенов вместо пользовательских заголовков или параметров в запросе/его теле 263 | 264 | Отправлять токены в параметрах запроса или его теле обычно не рекомендуется, поскольку эти параметры могут регистрироваться или кэшироваться различными системами, включая веб-серверы, прокси-серверы и шлюзы. Это потенциально может привести к раскрытию конфиденциальных данных, включая токены аутентификации. 265 | 266 | Кроме того, отправка токенов в параметрах запроса или его теле может сделать их более уязвимыми для атак с подделкой межсайтовых запросов (CSRF). При CSRF атаке злоумышленник может обманом заставить пользователя отправить запрос, включающий его токен аутентификации, который злоумышленник затем может использовать, чтобы выдать себя за пользователя и получить доступ к его учетной записи. 267 | 268 | Напротив, использование заголовка `Authorization` для отправки токенов гарантирует, что токены не регистрируются и не кэшируются промежуточными системами, а также может защитить от CSRF атак, позволяя серверу проверить токен перед обработкой запроса. 269 | 270 | ### Используйте только шифрование на стороне сервера 271 | 272 | > Используйте шифрование на стороне сервера, а не шифрование на стороне клиента 273 | 274 | Использовать шифрование на стороне клиента не рекомендуется, поскольку кодовую базу на стороне клиента можно легко воссоздать путём ревёрс-инжиниринга, что может привести к раскрытию алгоритмов шифрования. 275 | 276 | ### Используйте API шлюз для кэширования, правил, ограничивающих число запросов к ресурсу за определённый период времени и т. д. 277 | 278 | > Используйте шлюз API для кэширования, правил, ограничивающих число запросов к ресурсу за определённый период времени и других функций обеспечения защиты приложения 279 | 280 | API шлюз может сделать ваши API более безопасным, предоставляя централизованную точку контроля для управления и защиты API трафика. Ниже приведено несколько способов, с помощью которых API шлюз может улучшить безопасность API: 281 | 282 | * Аутентификация и авторизация: API шлюзы могут осуществлять аутентификацию и авторизацию пользователей, снижая нагрузку на отдельные API и улучшая согласованность во всей организации. Сюда могут входить такие технические решения, как проверка JWT, OAuth и другие механизмы аутентификации. 283 | 284 | * Фильтрация трафика и ограничение числа запросов: API шлюз может обеспечивать фильтрацию трафика и ограничение числа запросов для защиты API от DDoS-атак, атак методом «грубой силой» и других типов злоумышленного использования. 285 | 286 | * Шифрование и дешифрование: API шлюз может выполнять шифрование и дешифрование конфиденциальных данных для защиты от утечки и кражи данных. 287 | 288 | * Логирование и мониторинг: API шлюз может обеспечить централизованное логирование и мониторинг трафика API, помогая выявлять угрозы нарушения безопасности и другие проблемы и реагировать на них. 289 | 290 | * Интеграция с средствами обеспечения безопасности: API шлюз можно интегрировать с такими средствами обеспечения безопасности, как WAF, SIEM и другими инструментами, чтобы обеспечить дополнительные уровни защиты. 291 | 292 | ## Обработка выходных данных 293 | 294 | ### Отправляйте заголовок `X-Content-Type-Options: nosniff` 295 | 296 | > Отправляйте заголовок `X-Content-Type-Options: nosniff` 297 | 298 | Вам следует отправить заголовок `X-Content-Type-Options: nosniff`, чтобы предотвратить [атаки, связаные с анализом MIME типа](https://www.keycdn.com/support/what-is-mime-sniffing) в вашем веб-приложении. Этот заголовок сообщает браузеру не переопределять тип содержимого ответа, даже если он не является ожидаемым типом. Например, если злоумышленнику удастся загрузить HTML-файл с замаскированным расширением, например `.jpg`, сервер всё равно может отправить правильный заголовок `Content-type` для HTML-файла. Однако некоторые браузеры могут игнорировать этот заголовок и пытаться «проанализировать» `Content-type` на основе фактического содержимого файла, что приводит к потенциальной атаке с использованием межсайтового скриптинга (XSS). 299 | 300 | Отправляя заголовок `X-Content-Type-Options: nosniff`, вы указываете браузеру всегда доверять предоставленному `Content-type` и не пытаться анализировать тип контента. Это помогает снизить риск того, что злоумышленники воспользуются несоответствием типов контента для доставки вредоносного содержимого ничего не подозревающим пользователям. 301 | 302 | ### Отправляйте заголовок `X-Frame-Options: Deny` 303 | 304 | > Отправляйте заголовок `X-Frame-Options: Deny` 305 | 306 | Заголовок `X-Frame-Options` предотвращает возможность отображения страницы в iframe, что обычно используется при кликджекинг атаках. Установив для этого заголовка значение `Deny`, вы указываете браузеру не отображать страницу ни в каком iframe. Это помогает предотвратить внедрение страницы в веб-сайт злоумышленника и снижает риск атак с использованием кликджекинга. 307 | 308 | ### Отправляйте заголовок `Content-Security-Policy: default-src 'none'` 309 | 310 | > Отправляйте заголовок `Content-Security-Policy: default-src 'none'` 311 | 312 | Отправка заголовка `Content-Security-Policy: default-src 'none'` – это передовой метод обеспечения безопасности, который помогает предотвратить атаки с использованием межсайтового скриптинга (XSS). Этот заголовок сообщает браузеру, что он не должен разрешать загрузку каких-либо ресурсов из внешних источников, таких как скрипты, таблицы стилей или изображения. Он разрешает только ресурсы, которые явно внесены в белый список в заголовке CSP, например скрипты или таблицы стилей, размещенные в вашем собственном домене. Это может помочь предотвратить внедрение злоумышленниками кода на ваши веб-страницы с помощью XSS-атак, поскольку браузер не будет выполнять какие-либо скрипты или загружать какие-либо ресурсы, которые явно не разрешены политикой CSP. 313 | 314 | ### Удалите заголовки, которые могут облегчить идентификацию сервера (например, `x-powered-by` и т. д.) 315 | 316 | > Удалите заголовки, которые могут облегчить идентификацию сервера (например, `x-powered-by` и т. д.), из HTTP-запроса 317 | 318 | Эти заголовки можно помочь идентификацировать веб-сервер и его версию. Такая информация может быть использована злоумышленниками для выявления уязвимостей веб-сервера и их вредноносной эксплуатации. 319 | 320 | ### Принудительно задавайте заголовок `Content-type` для вашего ответа 321 | 322 | > Всегда принудительно задавайте заголовок `Content-Type` для соответствующего MIME типа 323 | 324 | Важно принудительно задавать `Content-Type` для безопасности API, поскольку это гарантирует, что клиент и сервер обмениваются передаваемыми данными во взаимно согласованном формате. Это может предотвратить такие атаки, как подмена или внедрение контента, когда злоумышленник пытается обманом заставить сервер обработать вредоносный контент, маскируя его другим типом. Принудительно задавая определенный формат `Content-Type` сервер может проверить, что получаемые им данные являются неподдельными и безопасными для обработки. Кроме того, принудительное указание `Content-Type` может помочь предотвратить определенные типы ошибок синтаксического анализа, которыми могут воспользоваться злоумышленники. 325 | 326 | ### Избегайте передачи в ответе конфиденциальных данных (учетных данных, аутентификационных токенов и т. д.) 327 | 328 | > Возвращайте только те данные, которые необходимы для работы клиента 329 | 330 | Возврат только тех данных, которые необходимы для работы клиента, является важной передовой практикой для безопасности API. Это связано с тем, что ограничение объема возвращаемых данных уменьшает объем раскрываемой конфиденциальной информации. Возвращая только необходимые данные, вы можете предотвратить уязвимость системы безопасности, такие как утечка данных, инъекционные атаки и другие типы атак, которые основаны на раскрытии слишком большого количества информации. Кроме того, уменьшение объема возвращаемых данных может повысить производительность вашего API за счет сокращения объема данных, которые необходимо обрабатывать и передавать. 331 | 332 | ### Возвращайте правильные коды ответа в соответствии с тем как закончилось выполнение операции 333 | 334 | > Возвращайте правильный код состояния в соответствии с тем как закончилось выполнение операции, например, 335 | > 336 | > * `200 OK` 337 | > * `400 Bad Request` 338 | > * `401 Unauthorized` 339 | > * `405 Method Not Allowed` 340 | > ... и т. д. 341 | 342 | Возврат правильного кода состояния в соответствии с тем как закончилось выполнение операции важен для безопасности API, поскольку позволяет клиенту понять результат своего запроса и предпринять соответствующие действия. Например, если сервер возвращает код состояния `401 Unauthorized` клиент понимает, что его учетные данные для аутентификации неверны, и может предложить пользователю повторно ввести свои данные для входа. Напротив, если сервер возвращает код состояния `200 OK`, даже если запрос не выполнен, клиент может не осознавать наличие проблемы и потенциально может выполнить вредоносные действия или отобразить неверные данные. Выдача правильных кодов состояния может помочь предотвратить возникновение уязвимостей в системе безопасности и повысить общую надежность и удобство использования API. 343 | 344 | ## CI & CD 345 | 346 | ### Проверяйте программную архитектуру и реализацию с помощью unit/интеграционных тестов 347 | 348 | > Проверяйте программную архитектуру и реализацию с помощью unit/интеграционных тестов 349 | 350 | Unit и интеграционное тестирование может помочь выявить уязвимости в коде и архитектуре API, такие как ошибки при проверке вводимых данных, недостатки аутентификации и авторизации, а также другие проблемы, связанные с безопасностью. Выполняя комплексное тестирование, разработчики могут гарантировать, что API работает должным образом и что он защищен от распространенных атак, таких как инъекционные атаки, межсайтовый скриптинг и других средств эксплуатации уязвимостей. Надлежащее тестирование также может помочь выявить и устранить узкие места в производительности, улучшить масштабируемость и надежность, а также обеспечить общее качество API. 351 | 352 | ### Используйте сode review (рецензирование кода, обзор кода, ревизия кода) и не полагайтесь только на себя 353 | 354 | > Используйте сode review и не полагайтесь только на себя 355 | 356 | Наличие хорошего процесса рецензирования кода позволяет другим членам команды просматривать код и выявлять потенциальные проблемы безопасности или уязвимости. В процессе рецензирования кода они проверяют код, чтобы убедиться, что он соответствует передовым практикам и является безопасным. Не полагайтесь только на себя; разработчик, написавший код, не должен быть единственным, кто несет ответственность за его разрешение на выливку в продакшен. Это помогает выявить потенциальные ошибки или упущения до развертывания кода, снижая риск брешей в системе безопасности или других проблем. 357 | 358 | ### Постоянно осуществляйте анализ безопасности вашего кода 359 | 360 | > Постоянно осуществляйте анализ безопасности вашего кода 361 | 362 | Непрерывный анализ безопасности помогает выявлять и устранять уязвимости, связанные с безопасностью в кодовой базе до того, как ими смогут воспользоваться злоумышленники. Он предполагает использование автоматизированных инструментов и ручных методов для сканирования кода на наличие потенциальных слабых мест, таких как небезопасные методы кодирования, ошибки конфигурации и устаревшие зависимости. Выявляя и устраняя уязвимости на ранних этапах цикла разработки, можно значительно снизить риск брешей в системе безопасности или потери данных, улучшая общий уровень безопасности системы. 363 | 364 | ### Проверьте свои зависимости на наличие известных уязвимостей 365 | 366 | > Проверьте свои зависимости на наличие известных уязвимостей и постоянно обновляйте их 367 | 368 | Уязвимости в сторонних библиотеках и компонентах могут быть использованы злоумышленниками для получения доступа к вашей системе или данным. Эти уязвимости могут возникнуть из-за устаревших или небезопасных зависимостей, которые не были обновлены последними патчами для устранения ошибок защиты. 369 | 370 | Регулярно проверяя уязвимости и обновляя зависимости, вы можете гарантировать, что ваш API не подвержен известным угрозам, связанным с нарушением безопасности. Это можно сделать с помощью автоматизированных инструментов или сервисов, которые сканируют вашу кодовую базу и предоставляют отчеты о любых уязвимостях, обнаруженных в ваших зависимостях. Своевременно устраняя эти уязвимости, вы можете снизить риск компрометации вашего API злоумышленниками. 371 | 372 | ### Разработайте механизм для отката версии, развёрнутой на продакшене 373 | 374 | > Разработайте механизм для отката версии, развёрнутой на продакшене 375 | 376 | Иногда развертывание новой версии API может привести к неожиданным ошибкам или проблемам, которые не были обнаружены во время тестирования. В таких случаях откат к предыдущей версии API может помочь смягчить последствия проблемы и восстановить работоспособность сервиса. Хорошо продуманное решение по откату может помочь сократить время пребывания в нерабочем состоянии и свести к минимуму влияние на пользователей. 377 | 378 | ## Мониторинг 379 | 380 | ### Используйте централизованный доступ (логин) для всех сервисов и компонентов 381 | 382 | > Используйте централизованный доступ (логин) для всех сервисов и компонентов 383 | 384 | Использование централизованного входа (логина) для всех сервисов и компонентов важно по нескольким причинам: 385 | 386 | * Централизованный вход в систему позволяет вам управлять аутентификацией и авторизацией в одном месте, снижая риск возникновения брешей в системе безопасности или несогласованности между различными сервисами. 387 | * Централизованный вход в систему обеспечивают единую точку входа, что позволяет вам легче контролировать доступ и отслеживать активность. 388 | * Централизованный вход в систему упрощает применение политик безопасности для различных сервисов и компонентов, гарантируя, что только авторизованные пользователи смогут получить доступ к конфиденциальным данным или выполнить определенные действия. 389 | 390 | Чтобы использовать централизованный вход в систему, вам необходимо настроить систему единого входа (SSO), которая позволит пользователям пройти аутентификацию один раз, а затем получать доступ к различным сервисам без необходимости повторного предоставления учетных данных. Это можно сделать с помощью таких протоколов, как OAuth или SAML, которые обеспечивают безопасную аутентификацию и авторизацию в различных приложениях и сервисах. После настройки вы можете использовать инструменты централизованного ведения логов, такие как стек ELK, Splunk или Graylog, для сбора логов из различных сервисов и компонентов и анализа их в одном месте. Это позволяет быстро выявлять угрозы безопасности или аномалии и реагировать на них. 391 | 392 | ### Используйте агентов для отслеживания всех запросов, ответов и ошибок 393 | 394 | > Используйте агентов для отслеживания всех запросов, ответов и ошибок 395 | 396 | Использование агентов для мониторинга всех запросов, ответов и ошибок позволяет отслеживать и обнаруживать любую аномальную активность или потенциальные атаки в режиме реального времени. Эти агенты можно настроить для отслеживания таких показателей, как время отклика, частота ошибок и характерные особенности использования приложения, что может помочь выявить любые аномалии, которые могут указывать на атаку. Отслеживание всех запросов и ответов, позволяет агентам вести сквозное наблюдение над поведением API, что может помочь выявить любые потенциальные уязвимости или слабые места в системе безопасности. Кроме того, агенты можно использовать для регистрации и анализа всех данных, проходящих через API, что может быть полезно для целей отладки и аудита. 397 | 398 | Чтобы использовать агенты для мониторинга, вместе с API можно развернуть специальное решение для мониторинга. Это решение можно настроить для сбора данных из всех запросов и ответов, а также для анализа данных на предмет любых аномалий или проблем. Агенты могут быть реализованы с использованием различных инструментов и технологий мониторинга, таких как агенты для мониторинга производительности приложений (APM), мониторинга логов и мониторинга сети. Агенты должны быть настроены так, чтобы передавали оповещения членам команды службы безопасности в режиме реального времени при обнаружении какой-либо подозрительной активности, что позволит принять немедленные меры. 399 | 400 | ### Используйте оповещения, отравляемые через SMS, Slack, электронную почту, Kibana, Cloudwatch и т. д. 401 | 402 | > Используйте оповещения, отравляемые через SMS, Slack, электронную почту, Kibana, Cloudwatch и т. д. 403 | 404 | Использование оповещений, отравляемые через различные каналы связи, таких как SMS, Slack, электронная почта, Kibana, Cloudwatch и т. д., может помочь вам быстро реагировать на любые проблемы или аномалии в вашей системе. Эти оповещения можно настроить так, чтобы они уведомляли вас в режиме реального времени о возникновении определенного события или условия, что позволяет вам принимать упреждающие меры для предотвращения времени пребывания в неработоспособном состоянии, потери данных или нарушений безопасности. Кроме того, оповещения могут предоставить ценную информацию о производительности системы и поведении пользователей, позволяя вам принимать обоснованные решения, касающиеся разработки и реализации вашего API. 405 | 406 | ### Убедитесь, что вы не пишите в лог никакие конфиденциальные данные 407 | 408 | > Убедитесь, что вы не пишите в лог никакие конфиденциальные данные 409 | 410 | Убедитесь, что вы не пишите в лог какие-либо конфиденциальные данные, такие как пароли, номера кредитных карт или личную информацию. Это связано с тем, что логи с конфиденциальными данными момогут попасть в руки злоумышленников, что позволит им получить несанкционированный доступ к вашей системе или данным. Кроме того, регистрация конфиденциальных данных может нарушать законы и нормативные требования о конфиденциальности данных и вас могут привлечь к юридической ответственности. 411 | 412 | ### Используйте IDS и/или IPS систему для мониторинга всего необходимого 413 | 414 | > Используйте IDS и/или IPS системы для обнаружения и блокирования атак 415 | 416 | Системы обнаружения вторжений (Intrusion detection systems, IDS) и системы предотвращения вторжений (Intrusion prevention systems, IPS) могут использоваться для обнаружения и блокирования атак. Эти системы можно настроить для мониторинга всего входящего и исходящего трафика и обнаружения любой подозрительной активности. Если обнаружена какая-либо подозрительная активность, системы можно настроить на блокировку трафика, предотвращая успешность атаки. IDS и IPS системы могут быть реализованы с использованием различных инструментов и технологий, таких как системы обнаружения вторжений в сеть (Network intrusion detection systems, NIDS), системы обнаружения вторжений на основе хоста (Host-based intrusion detection systems, HIDS) и системы предотвращения вторжений в сеть (Network intrusion prevention systems, NIPS). Эти системы можно развернуть вместе с API и настроить для мониторинга всего входящего и исходящего трафика. Системы можно настроить так, чтобы они в режиме реального времени оповещали членов команды службы безопасности при обнаружении какой-либо подозрительной активности, что позволяет принять немедленные меры. 417 | 418 | ## Список рекомендованных ссылок по теме 419 | 420 | * [Collection of Resources for Building APIs](https://github.com/yosriady/awesome-api-devtools) 421 | * [CS253: Web Security](https://www.youtube.com/watch?v=5JJrJGZ_LjM&list=PL1y1iaEtjSYiiSGVlL1cHsXN_kvJOOhu-) 422 | * [Securing Web Applications](https://www.youtube.com/watch?v=WlmKwIe9z1Q) 423 | * [MIT 6.858: Computer Systems Security](https://www.youtube.com/watch?v=GqmQg-cszw4&list=PLUl4u3cNGP62K2DjQLRxDNRi0z2IRWnNh) 424 | -------------------------------------------------------------------------------- /inheritanceVsCompositionVsAggregation.md: -------------------------------------------------------------------------------- 1 | ## Наследование vs Композиция vs Агрегация 2 | 3 | [Смотри также](http://sergeyteplyakov.blogspot.com/2012/12/vs-vs.html) 4 | 5 | Между двумя классами/объектами существует разные типы отношений. Самым базовым типом отношений является ассоциация (*association*), 6 | это означает, что два класса как-то связаны между собой. Обычно это отношение используется на ранних этапах дизайна, чтобы показать 7 | существующую зависимость между классами. 8 | 9 | Более точным типом отношений является отношение *открытого наследования* (отношение «является», IS A Relationship), 10 | которое говорит, что все, что справедливо для базового класса справедливо и для его наследника. 11 | Именно с его помощью мы получаем полиморфное поведение, абстрагируемся от конкретной реализации классов, 12 | имея дело лишь с абстракциями (интерфейсами или базовыми классами) и не обращаем внимание на детали реализации. 13 | 14 | ```php 15 | save(); 32 | ``` 33 | 34 | И хотя наследование является отличным инструментом, его явно недостаточно для решения всех типов задач. 35 | Во-первых, далеко не все отношения между классами определяются отношением «является», а во-вторых, 36 | наследование является самой сильной связью между двумя классами, которую невозможно разорвать во время исполнения. 37 | 38 | В этом случае нам на помощь приходит другая пара отношений: композиция (**composition**) и агрегация (**aggregation**). 39 | Оба они моделируют отношение «является частью» (HAS-A Relationship) и обычно выражаются в том, 40 | что класс целого содержит поля (или свойства) своих составных частей. Грань между ними достаточно тонкая, 41 | но важная, особенно в контексте управления зависимостями. 42 | 43 | Разница между композицией и агрегацией заключается в том, что **в случае композиции целое явно контролирует время жизни своей составной части** 44 | (часть не существует без целого), а **в случае агрегации целое хоть и содержит свою составную часть, время их жизни не связано** 45 | (например, составная часть передается через параметры конструктора). 46 | 47 | ```php 48 | customRepository = new CustomRepository(); 65 | } 66 | 67 | public function doSomething(): void 68 | { 69 | // do some work 70 | echo "Do some work\n"; 71 | // save data 72 | $this->customRepository->save(); 73 | } 74 | } 75 | 76 | $service = new CompositeCustomService(); 77 | $service->doSomething(); 78 | 79 | class AggregatedCustomService 80 | { 81 | // Агрегация 82 | private $customRepository; 83 | public function __construct(CustomRepository $customRepository) 84 | { 85 | $this->customRepository = $customRepository; 86 | } 87 | 88 | public function doSomething(): void 89 | { 90 | // do some work 91 | echo "Do some work\n"; 92 | // save data 93 | $this->customRepository->save(); 94 | } 95 | } 96 | 97 | $repo = new CustomRepository(); 98 | $service = new AggregatedCustomService($repo); 99 | $service->doSomething(); 100 | ``` 101 | 102 | **CompositeCustomService** для управления своими составными частями использует композицию, а **AggregatedCustomService** – агрегацию. 103 | При этом явный контроль времени жизни обычно приводит к более высокой связанности между целым и частью, поскольку используется конкретный тип, 104 | тесно связывающий участников между собой. 105 | 106 | Мы можем использовать композицию и контролировать время жизни объекта, не завязываясь на конкретные типы. Например, с помощью фабричного метода: 107 | 108 | ```php 109 | connectionFactory = $connectionFactory; 173 | } 174 | 175 | public function doSomething(): void 176 | { 177 | // Композиция 178 | $dbConnection = $this->connectionFactory::factory(self::DB_TYPE); 179 | $dbConnection->connect(); 180 | // do some work 181 | echo "Do some work\n"; 182 | $dbConnection->close(); 183 | } 184 | } 185 | 186 | $factory = new ConnectionFactory(); 187 | $service = new CustomService($factory); 188 | $service->doSomething(); 189 | ``` 190 | 191 | Задачу с сервисами и репозиториями можно решить как с помощью наследования, так и с помощью агрегации. Каждый вариант 192 | приводит к одному и тому же конечному результату, при этом связанность изменяется от очень высокой (при наследовании) 193 | к очень слабой (при агрегации). 194 | 195 | В большинстве случаев следует предпочесть агрегацию наследованию, поскольку первая дает большую гибкость и динамичность во время исполнения. 196 | -------------------------------------------------------------------------------- /interfaces.md: -------------------------------------------------------------------------------- 1 | # [Интерфейсы](http://php.net/manual/ru/language.oop5.interfaces.php) 2 | 3 | Интерфейсы объектов позволяют создавать код, который указывает, какие методы должен реализовать класс, без необходимости определять, как эти методы обрабатываются. 4 | 5 | Интерфейсы объявляются так же, как и обычные классы, но с использованием ключевого слова `interface` вместо `class`. Тела методов интерфейсов должны быть пустыми. 6 | 7 | Для реализации интерфейса используется оператор `implements`. Класс должен реализовать все методы, описанные в интерфейсе, иначе произойдет фатальная ошибка. При желании классы могут реализовывать более одного интерфейса, разделяя каждый интерфейс запятой. 8 | 9 | ```php 10 | vars[$name] = $var; 28 | } 29 | 30 | public function getHtml($template) 31 | { 32 | foreach($this->vars as $name => $value) { 33 | $template = str_replace('{' . $name . '}', $value, $template); 34 | } 35 | 36 | return $template; 37 | } 38 | } 39 | ?> 40 | ``` 41 | 42 | Все методы, определенные в интерфейсы должны быть объявлены как `public`. 43 | 44 | Интерфейс может содержать публичные методы (простые и статические), а также константы. Интерфейс НЕ может содержать любые свойства, непубличные методы и константы, методы с реализацией. 45 | 46 | В РНР не поддерживается множественное наследование. Однако эту проблему можно решить с помощью интерфейсов. Другими словами, для каждого класса в РНР может существовать только один родительский класс. Тем не менее в каждом классе можно реализовать произвольное количество интерфейсов. При этом данный класс будет соответствовать типам всех тех интерфейсов, которые в нем реализованы. 47 | -------------------------------------------------------------------------------- /lastStaticBindings.md: -------------------------------------------------------------------------------- 1 | # [Позднее статическое связывание](http://php.net/manual/ru/language.oop5.late-static-bindings.php) 2 | 3 | Позднее статическое связывание может быть использовано для того, чтобы получить ссылку на вызываемый класс в контексте статического наследования. "Позднее связывание" отражает тот факт, что обращения через static:: не будут вычисляться по отношению к классу, в котором вызываемый метод определен, а будут вычисляться на основе информации в ходе исполнения. 4 | 5 | # Использование static:: 6 | 7 | ```php 8 | 26 | ``` 27 | 28 | Позднее статическое связывание может использоваться, чтобы избежать дублирования кода из родительсикх классов в дочерние. 29 | 30 | ```php 31 | abstract class DomainObject 32 | { 33 | public static function create () 34 | { 35 | return new static (); 36 | } 37 | class User extends DomainObject () 38 | { 39 | } 40 | class Document extends DomainObject () 41 | { 42 | } 43 | print_r(Document::create()); 44 | ``` 45 | 46 | Ключевое слово static можно использовать не только для создания объектов. Так же, как и self и parent, его можно использовать как идентификатор для вызова статических методов даже из нестатического контекста. 47 | 48 | ```php 49 | abstract class DomainObject 50 | { 51 | private $group; 52 | public function __construct() 53 | { 54 | $this->group = static::getGroup(); 55 | } 56 | public static function create(): DomainObject 57 | { 58 | return new static(); 59 | } 60 | public static function getGroup(): string 61 | { 62 | return "default"; 63 | } 64 | } 65 | class User extends DomainObject 66 | { 67 | } 68 | class Document extends DomainObject 69 | { 70 | public static function getGroup(): string 71 | { 72 | return "document"; 73 | } 74 | } 75 | class SpreadSheet extends Document 76 | { 77 | } 78 | 79 | print_r(User::create()); 80 | print_r(SpreadSheet::create()); 81 | 82 | ``` 83 | -------------------------------------------------------------------------------- /singleton.md: -------------------------------------------------------------------------------- 1 | # Шаблон проектирования Singleton 2 | 3 | Ссылка (https://designpatternsphp.readthedocs.io/ru/latest/Creational/Singleton/README.html#singleton) 4 | -------------------------------------------------------------------------------- /software-design-and-architecture.md: -------------------------------------------------------------------------------- 1 | [Оригинал](https://roadmap.sh/software-design-architecture) 2 | 3 | Полезные ссылки: 4 | 5 | * [How to Learn Software Design and Architecture | The Full-stack Software Design & Architecture Map](https://khalilstemmler.com/articles/software-design-architecture/full-stack-software-design/) 6 | 7 | # Основные принципы проектирования программного обеспечения и виды архитектур приложений 8 | 9 | ## Принципы проектирования, базирующиеся на понятии «чистого кода» 10 | 11 | Чистый код — это код, который легко читать, понимать и поддерживать. Он следует набору принципов, призванных сделать код более читабельным, тестируемым и менее подверженным ошибкам. Вот некоторые из ключевых принципов чистого кода: 12 | 13 | * Ясность: код должен быть легко читаемым и понятным. 14 | * Простота: код должен быть максимально простым, избегающим ненужной сложности. 15 | * Комментарии. Комментарии следует использовать с осторожностью и только в случае необходимости для объяснения сложного или неочевидного кода. 16 | * Именование: переменные, функции и классы должны иметь осмысленные и содержательные имена. 17 | * Форматирование: код должен быть последовательно отформатирован для повышения читабельности. 18 | * Функциональность: код должен быть организован в виде небольших функций и классов, выполняющих какую-то одну специализированную задачу. 19 | * Обработка ошибок: код должен обрабатывать ошибки последовательным и предсказуемым образом. 20 | * Тестирование: код должен быть тестируемым и иметь высокое покрытие тестами. 21 | * Повторное использование: код должен быть многократно используемым и модульным. 22 | * Производительность: код должен быть эффективным и производительным. 23 | 24 | Полезные ссылки: 25 | 26 | * [Introduction to Clean Code & Software Design Principles](https://workat.tech/machine-coding/tutorial/introduction-clean-code-software-design-principles-nwu4qqc63e09) 27 | 28 | ### Будьте последовательны при написании кода 29 | 30 | Быть последовательным означает использовать одну и ту же однотипную манеру при написании кода. Она может включать использование принятых соглашений об именах, структур данных и интерфейсов во всей системе, а также соблюдение установленных в команде принципов проектирования и лучших практик. Такая последовательность поможет сделать систему более удобной в сопровождении, понятной и расширяемой. 31 | 32 | Полезные ссылки: 33 | 34 | * [10 Tips for Writing Clean Code](https://www.pluralsight.com/blog/software-development/10-steps-to-clean-code) 35 | 36 | ### Содержательные, понятные названия переменных, не требующие дополнительных комментариев 37 | 38 | Вы должны придерживаться практики давать четкие и содержительные имена различным компонентам системы, таким как переменные, функции и классы. Это поможет сделать систему более понятной и удобной в сопровождении за счет четкого указания назначения каждого компонента и его предполагаемого использования. 39 | 40 | Использование осмысленных имен важно для того, чтобы сделать код понятным, читаемым и легким для понимания. Содержательные имена могут помочь передать назначение и функцию переменных, функций, классов и других элементов кода. 41 | 42 | Ниже приведены некоторые примеры использования содержительных имен в системной архитектуре: 43 | 44 | * Используйте описательные и осмысленные имена для переменных, функций, классов и других элементов кода. 45 | * Используйте принятые командой соглашения об именах во всей кодовой базе, такие как camelCase для переменных и PascalCase для функций и классов. 46 | * Используйте аббревиатуры и акронимы с осторожностью и только в том случае, если они понятны всем членам команды. 47 | * Используйте осмысленные префиксы или суффиксы для указания типа или назначения переменной или функции, например «is» или «get» для логических переменных или «list» для переменных-массивов. 48 | * Избегайте использования однобуквенных имён переменных или ничем не примечательных имён, таких как «temp» или «x», которые не несут никакой смысловой нагрузки. 49 | * Избегайте использования слишком длинных или сложных имен, которые затрудняют чтение кода. 50 | 51 | Полезные ссылки: 52 | 53 | * [A Guide for Naming Things in Programming](https://levelup.gitconnected.com/a-guide-for-naming-things-in-programming-2dc2d74879f8) 54 | * [How to Write Meaningful Variable Names?](https://workat.tech/machine-coding/tutorial/writing-meaningful-variable-names-clean-code-za4m83tiesy0) 55 | 56 | ### Стиль программирования: отступы 57 | 58 | Использование отступов позволяет на практике визуально сгруппировать связанные строки кода вместе, что облегчает чтение и понимание структуры кода. Выбор того или иного количества пробелов для отступа относится к соглашениям и рекомендациям, принятым внутри команды, которые используются для форматирования и структурирования кода, по аналогии с соглашениями об именах, комментариях и использовании пробелов. 59 | 60 | Наличие единого стиля поможет сделать код более читаемым и понятным, что может повысить удобство сопровождения системы. 61 | 62 | Полезные ссылки: 63 | 64 | * [Clean Code – Formatting](https://www.baeldung.com/cs/clean-code-formatting) 65 | 66 | ### Старайтесь, чтобы создаваемые методы, классы, файлы, были как можно меньше 67 | 68 | Старайтесь проектировать и создавать небольшие специализированные компоненты, которые решают определенную задачу, а не большие монолитные компоненты, которые пытаются сделать всё сразу. Это поможет улучшить удобство сопровождения и масштабируемость системы, облегчая понимание, тестирование и модификацию отдельных компонентов. 69 | 70 | ### Используйте чистые функции 71 | 72 | Чистая функция — это функция определенного типа, удовлетворяющая следующим критериям: 73 | 74 | * Она принимает некоторые входные данные, называемые аргументами, и возвращает значение или выходные данные. 75 | * Она не приводит к каким-либо наблюдаемым побочным эффектам, таких как изменение состояния системы или взаимодействие с внешними ресурсами. 76 | * При одних и тех же входных данных она всегда будет возвращать один и тот же результат. 77 | * Она не зависит ни от какого состояния или переменных, которые находятся за пределами её области видимости. 78 | 79 | Чистые функции считаются более предсказуемыми и их легче тестировать, поскольку их поведение определяется исключительно поступающими на вход данными и их внутренней логикой. Они также облегчают анализ поведения программы, поскольку на результат чистой функции не влияют никакие внешние факторы. Чистые функции часто используются в функциональном программировании, где они считаются важнейшим принципом. Их также используют в конкурентном и параллельном программировании, поскольку они менее подвержены эффектам гонки данных и другим проблемам, связанным с параллелизмом. 80 | 81 | [Википедия - Чистота функции](https://ru.wikipedia.org/wiki/%D0%A7%D0%B8%D1%81%D1%82%D0%BE%D1%82%D0%B0_%D1%84%D1%83%D0%BD%D0%BA%D1%86%D0%B8%D0%B8) 82 | 83 | ### Минимизируйте цикломатическую сложность программы 84 | 85 | Цикломатическая сложность — это мера структурной сложности программы, которая определяется количеством линейно независимых путей в порядке выполнения программы. Высокая цикломатическая сложность может затруднить понимание, тестирование и сопровождение программы, поэтому часто желательно свести ее к минимуму в архитектуре системы. 86 | 87 | Ниже показано несколько способов минимизировать цикломатическую сложность в архитектуре системы: 88 | 89 | * Разбейте сложные функции на более мелкие и простые функции, выполняющие определенные задачи. 90 | * Используйте управляющие конструкции, такие как операторы if-else и циклы, согласованным и предсказуемым образом. 91 | * Используйте понятия и методы функционального программирования, такие как неизменяемость и чистые функции, чтобы уменьшить потребность в сложном порядке выполнения. 92 | * Используйте шаблоны проектирования, такие как шаблон состояния, для упрощения сложного порядка выполнения. 93 | * Регулярно просматривайте код и реорганизуйте его, чтобы упростить порядок выполнения. 94 | * Используйте инструменты статического анализа кода, которые могут обнаруживать и сообщать о высокой цикломатической сложности кода. 95 | 96 | Следуя этим рекомендациям, архитектура системы будет более удобной в сопровождении, тестируемой и менее подверженной ошибкам. 97 | 98 | Полезные ссылки: 99 | 100 | * [How to reduce cyclomatic complexity?](https://kasp9023.medium.com/how-to-make-your-code-more-readable-focus-on-the-happy-path-and-reduce-cyclomatic-complexity-66802b8897b5) 101 | * [Википедия - Цикломатическая сложность](https://ru.wikipedia.org/wiki/%D0%A6%D0%B8%D0%BA%D0%BB%D0%BE%D0%BC%D0%B0%D1%82%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%B0%D1%8F_%D1%81%D0%BB%D0%BE%D0%B6%D0%BD%D0%BE%D1%81%D1%82%D1%8C) 102 | 103 | ### Старайтесь не передавать значения типа null и булевого типа 104 | 105 | Передача значения типа `null` или булевых (логических) значений может привести к неожиданному поведению и трудным для отладки ошибкам в программе. Вот несколько способов избежать передачи значения типа `null` или булевых значений в архитектуре системы: 106 | 107 | * Используйте типы `Optionals` или `Maybe` вместо `null`, чтобы указать на отсутствие значения. Это позволяет понять, когда значение отсутствует, и предотвращает возникновение исключений, связанных с тем, что указатель ссылается на `null`. 108 | * Используйте значение по умолчанию для аргументов функции вместо того, чтобы позволять им быть равными `null` или значениям логического типа. Это устраняет необходимость проверки на `null` или значения логического типа и снижает вероятность ошибок. 109 | * Используйте шаблон `Null Object` для замены значений типа `null` специальным объектом с определенным поведением. Это устраняет необходимость проверки на `null` и делает код более читабельным. 110 | * Используйте тернарный оператор (?:) вместо операторов if-else при работе с логическими значениями. Это может сделать код более компактным и удобным для чтения. 111 | * Используйте функцию `assert`, чтобы проверить допустимость аргументов функции и создать исключение, если они не удовлетворяют требованиям. 112 | 113 | Следуя этим рекомендациям, архитектура системы будет более надежной и менее подверженной ошибкам. 114 | 115 | ### Следите за тем, что код фреймворка был дистанцирован 116 | 117 | Дистанцирование кода фреймворка означает отделение кода приложения от кода фреймворка. Это упрощает независимое обслуживание, тестирование и обновление кодовой базы приложения и фреймворка. 118 | 119 | Вот несколько способов, позволяющих отделить код фреймворка от архитектуры системы: 120 | 121 | 1. Используйте уровень абстракции, чтобы отделить код приложения от кода фреймворка. Это позволяет писать код приложения без необходимости знать специфику фреймворка. 122 | 2. Используйте внедрение зависимостей, чтобы отделить код приложения от кода фреймворка. Это позволяет коду приложения использовать функциональные возможности фреймворка без необходимости непосредственного создания экземпляров объектов фреймворка. 123 | 3. Избегайте использования специфичных для фреймворка библиотек или классов в коде приложения. Это упрощает переход на другой фреймворк в будущем, если это будет необходимо. 124 | 4. Используйте стандартный интерфейс кода приложения для взаимодействия с фреймворком. Это позволяет писать код приложения без необходимости знать специфику фреймворка. 125 | 5. Располагайте приложение и код фреймворка в отдельных проектах и/или репозиториях. 126 | 127 | Следуя этим рекомендациям, архитектура системы будет более удобной в сопровождении, тестируемой и менее подверженной ошибкам, а также будет проще обновлять или переходить на другой фреймворк в случае необходимости. 128 | 129 | Полезные ссылки: 130 | 131 | * [Clean architecture](https://pusher.com/tutorials/clean-architecture-introduction/) 132 | 133 | ### Используйте надлежащие программные конструкции 134 | 135 | С точки зрения принципов чистого кода «использование надлежащих программных конструкций» означает применение соответствующих программных конструкций, таких как циклы, условные операторы и функции, таким образом, чтобы сделать код простым для понимания, поддержки и изменения. 136 | 137 | При использовании надлежащих конструкций код должен быть организован логично и интуитивно понятно, с использованием соответствующих операторов, определяющих порядок выполнения, и структур данных для реализации поставленной задачи. Это также означает, что следует избегать ненужных или слишком сложных конструкций в коде, которые усложняют его понимание или осмысление. 138 | 139 | Кроме того, фраза «надлежащие конструкции» также означает использование правильных конструкций для соответствующей задачи, например, если вы хотите выполнить итерацию по массиву, воспользуйтесь циклом `for` вместо рекурсии. А ещё вам следует избегать глобальных переменных и вместо этого использовать аргументы функций и возвращать значения для передачи данных между разными частями кода. 140 | 141 | При использовании надлежащих конструкций код будет более читабельным, удобным для сопровождения и менее подверженным ошибкам, что упростит другим разработчикам понимание, отладку и расширение кода. 142 | 143 | ### Тесты должны выполняться быстро и быть независимыми 144 | 145 | Независимость тестов гарантируует, что тесты надежны, воспроизводимы и их легко поддерживать. Когда тесты независимы, изменение одного теста не повлияет на результаты других тестов. 146 | 147 | Ниже приведено несколько способов сделать тесты независимыми в архитектуре системы: 148 | 149 | * Используйте внедрение зависимостей, чтобы отделить код теста от кода приложения. Это позволяет запускать тесты без необходимости непосредственно создавать экземпляры объектов приложения. 150 | * Используйте имитации для реализации объектов или заглушки, чтобы изолировать тест от внешних зависимостей, таких как базы данных, API или другие сервисы. 151 | * Используйте автономные тестовые данные, не зависящие от внешних данных или состояния. 152 | * Используйте фреймворк для тестирования, поддерживающий параллельное выполнение тестов, чтобы их можно было запускать независимо друг от друга. 153 | * Используйте разработку через тестирование (TDD), которая предполагает написание тестов до написания кода приложения. Это гарантирует, что тесты независимы и что код написан с учетом возможности его тестирования. 154 | * Избегайте глобального состояния и совместно используемого изменяемого состояния, так как это может привести к неожиданным результатам. 155 | 156 | Полезные ссылки: 157 | 158 | * [Keeping Tests Valuable](https://www.checklyhq.com/learn/headless/valuable-tests/) 159 | 160 | ### Группируйте код вокруг а́ктора, к которому он относится 161 | 162 | «Код вокруг а́ктора» — это методика разработки программного обеспечения, который мотивирует разработчиков организовывать свой код вокруг а́кторов или сущностей, которые с ним взаимодействуют. Áкторами могут быть пользователи, системы или процессы, выполняющие определенную роль или функцию в приложении. Этот подход помогает четко разделить задачи, делая код более модульным, пригодным для повторного использования и более простым для понимания. 163 | 164 | Полезные ссылки: 165 | 166 | * [Actor Model Architecture](https://awesome-architecture.com/actor-model-architecture/actor-model-architecture/) 167 | * [Inversion of Control](https://stackoverflow.com/a/72826245) 168 | * [Википедия - Модель акторов](https://ru.wikipedia.org/wiki/%D0%9C%D0%BE%D0%B4%D0%B5%D0%BB%D1%8C_%D0%B0%D0%BA%D1%82%D0%BE%D1%80%D0%BE%D0%B2) 169 | 170 | ### Разделяйте на команды и запросы 171 | 172 | Разделение на команды и запросы (Command-Query Separation, CQS) — это принцип разработки программного обеспечения, при котором обязанности метода или функции разделяются на две категории: команды и запросы. Команды — это методы, которые изменяют состояние системы, а запросы — это методы, которые возвращают информацию, но не изменяют состояние системы. 173 | 174 | Полезные ссылки: 175 | 176 | * [CQRS Pattern](https://learn.microsoft.com/en-us/azure/architecture/patterns/cqrs) 177 | 178 | ### Избегайте ненужной сложности и осуществляйте рефакторинг как можно чаще 179 | 180 | **Не спешите создавать абстракции** 181 | 182 | Создание абстракций — важная часть разработки программного обеспечения, но создание слишком большого количества абстракций или их слишком преждевременное создание может привести к ненужной сложности и затруднить понимание и сопровождение кода. 183 | 184 | Вот несколько способов избежать необдуманного создания абстракций в системной архитектуре: 185 | 186 | * Поймите проблему, которую необходимо решить, прежде чем создавать абстракцию. 187 | * Начните с простого решения и создавайте абстракцию только тогда, когда станет ясно, что решение становится слишком сложным. 188 | * Используйте методы рефакторинга кода, чтобы упростить код перед созданием абстракции. 189 | * Избегайте создания абстракций ради создания абстракций. 190 | * Используйте признанные в сообществе шаблоны и методы проектирования при создании абстракций, но не внедряйте насильно их в код. 191 | * Используйте автоматизированное тестирование, чтобы гарантировать, что абстракция не приведет к появлению новых ошибок или нарушению существующей функциональности. 192 | * Создавайте абстракции таким образом, чтобы их было легко тестировать, отлаживать и анализировать. 193 | 194 | Полезные ссылки: 195 | 196 | * [AHA Programming](https://kentcdodds.com/blog/aha-programming) 197 | * Фаулер М. Рефакторинг: улучшение существующего кода. - Пер. с англ. - СПб: Символ-Плюс, 2003. - 432 с, ил. 198 | 199 | ## Парадигмы программирования 200 | 201 | Парадигма программирования — это фундаментальный стиль или подход к решению проблем с использованием языка программирования. Различные парадигмы программирования предоставляют разные способы организации и структурирования кода и имеют разные сильные и слабые стороны. Некоторые из наиболее распространенных парадигм программирования включают в себя: 202 | 203 | * Императивное программирование 204 | * Функциональное программирование 205 | * Объектно-ориентированное программирование 206 | * Логическое программирование 207 | * Декларативное программирование 208 | 209 | Полезные ссылки: 210 | 211 | * [Overview of Programming paradigm](https://en.wikipedia.org/wiki/Programming_paradigm) 212 | * [Introduction of Programming Paradigms](https://www.geeksforgeeks.org/introduction-of-programming-paradigms/) 213 | * [Википедия - Парадигма программирования](https://ru.wikipedia.org/wiki/%D0%9F%D0%B0%D1%80%D0%B0%D0%B4%D0%B8%D0%B3%D0%BC%D0%B0_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F) 214 | 215 | ### Структурное программирование 216 | 217 | Структурное программирование — это парадигма программирования, которая делает упор на использование структурированных управляющих конструкций, изменющих ход выполнения программы, таких как циклы и условные операторы, для организации кода в логические, простые для понимания блоки. Это способ написания компьютерных программ, в котором особое внимание уделяется использованию процедур и функций, а также структур данных для организации кода и упрощения его понимания, отладки и поддержки. Основная идея структурного программирования состоит в том, чтобы разбить программу на более мелкие части, которые просто контролировать, можно легко понять, протестировать и изменить. Этот подход выступает против использования операторов «goto», которые считаются неструктурированными и могут привести к сложному для чтения и сопровождения коду. 218 | 219 | Полезные ссылки: 220 | 221 | * [Overview of Structured programming](https://www.techtarget.com/searchsoftwarequality/definition/structured-programming-modular-programming) 222 | 223 | ### Функциональное программирование 224 | 225 | Функциональное программирование — это парадигма программирования, которая делает упор на использование чистых функций и неизменяемых данных. Это способ написания компьютерных программ, который акцентирует внимание на использовании функций и математических понятий, таких как рекурсия, а не на использование объектов и классов, как в объектно-ориентированном программировании. В функциональном программировании функции являются «объектами первого класса» (функции высших порядков), что означает, что они могут быть переданы в качестве аргументов другим функциям и возвращены в качестве результата. 226 | 227 | Функциональное программирование поощряет неизменяемость, что означает, что после того, как переменной присвоено значение, его нельзя изменить. Это может упростить код, так как устраняет необходимость управления состоянием и ошибок, которые могут возникнуть при этом. 228 | 229 | Полезные ссылки: 230 | 231 | * [What is Functional Programming?](https://www.codingdojo.com/blog/what-is-functional-programming) 232 | * [Tutorial - Functional Programming?](https://www.youtube.com/watch?v=dAPL7MQGjyM) 233 | 234 | ### Объектно-ориентированное программирование 235 | 236 | Объектно-ориентированное программирование (ООП) — это парадигма программирования, основанная на понятии «объектов», которые являются экземплярами классов. ООП — это способ организации и структурирования кода, основанный на принципах инкапсуляции, наследования и полиморфизма. 237 | 238 | Инкапсуляция — это идея, заключающаяся в том, что внутреннее состояние объекта должно быть скрыто и доступно только через его методы. Это позволяет объекту контролировать, как используются его данные, и не позволяет внешнему коду вносить недопустимые изменения в состояние объекта. 239 | 240 | В ООП класс — это шаблон для создания объектов, которые имеют как данные (атрибуты), так и поведение (методы). Основная идея ООП заключается в моделировании объектов реального мира и их взаимодействий, что делает его подходящим для создания сложных и крупномасштабных программных систем. 241 | 242 | Полезные ссылки: 243 | 244 | * [What is Object Oriented Programming?](https://www.youtube.com/watch?v=pTB0EiLXUC8) 245 | * [Overview of Object-Oriented Programming (OOP)](https://en.wikipedia.org/wiki/Object-oriented_programming) 246 | * [Википедия - Объектно-ориентированное программирование](https://ru.wikipedia.org/wiki/%D0%9E%D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D0%BD%D0%BE-%D0%BE%D1%80%D0%B8%D0%B5%D0%BD%D1%82%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%BD%D0%BE%D0%B5_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5) 247 | * [Discover Object Oriented Programming](https://blog.hubspot.com/website/object-oriented-programming) 248 | * [Software Development Tutorial - What is object-oriented language?](https://www.youtube.com/watch?v=SS-9y0H3Si8) 249 | 250 | #### Модельно-ориентированный подход к проектированию 251 | 252 | Модельно-ориентированный подход к проектированию (MDD) — это методология разработки программного обеспечения, в которой проектирование системы осуществляется с помощью набора моделей, используемые для управления процессом разработки системы. MDD основан на идее, что конструкция системы может быть представлена набором моделей и что эти модели могут быть применены для генерации кода для системы. 253 | 254 | Основное преимущество использования MDD заключается в том, что он позволяет четко разделить задачи проектирования и реализации системы. Модели представляют структуру системы, а код генерируется на основе моделей, что упрощает поддержку и развитие системы. Кроме того, MDD также может улучшить качество кода, поскольку модели можно использовать для проверки ошибок проектирования и несоответствий до создания кода. 255 | 256 | Полезные ссылки: 257 | 258 | * [Model Driven Design – theory to practice](https://www.todaysoftmag.com/article/1529/model-driven-design-theory-to-practice) 259 | 260 | ##### Модель предметной области 261 | 262 | Модель предметной области — это воплощение конкретной области знаний или бизнеса, которое используется для моделирования объектов и понятий в этой предметной области, а также для определения взаимосвязей и ограничений между ними. В объектно-ориентированном программировании (ООП) модель предметной области обычно представлена набором классов и интерфейсов, где каждый класс или интерфейс представляет определенное понятие или объект в предметной области. 263 | 264 | Модель предметной области используется для обеспечения четкого и последовательного представления предметной области, а также для отражения бизнес-требований и ограничений системы. Она также применяется в качестве ориентира при проектировании системы и для гарантирования того, чтобы система точно отражала реальную проблему, которую она призвана решать. 265 | 266 | Полезные ссылки: 267 | 268 | * [Overview of Domain model](https://en.wikipedia.org/wiki/Domain_model) 269 | * [Domain Driven Design](https://khalilstemmler.com/articles/categories/domain-driven-design/) 270 | 271 | ##### Анемичная модель 272 | 273 | Анемичная модель, также известная как анемичная модель предметной области, представляет собой тип модели предметной области, в которой объекты предметной области содержат только данные (атрибуты) и не имеют поведения. Анемичная модель часто приводит к использованию объектов переноса данных (DTO) и сервисного уровня для реализации поведения. 274 | 275 | Анемичная модель считается антишаблоном в объектно-ориентированном программировании (ООП), потому что она нарушает принципы инкапсуляции и разделения ответственности. В анемичной модели поведение отделено от данных и обычно реализуется на отдельном сервисном уровне, что может привести к сложному, сильно связанному и сложному в сопровождении коду. 276 | 277 | Полезные ссылки: 278 | 279 | * [Overview of Anemic Domain Model](https://en.wikipedia.org/wiki/Anemic_domain_model) 280 | * [What is an Anaemic Domain Model?](https://www.ensonodigital.com/blog/anaemic-domain-model-vs-rich-domain-model) 281 | 282 | ##### Многоуровневые архитектуры 283 | 284 | Многоуровневая архитектура — это шаблон проектирования программного обеспечения, в котором функциональность системы разделена на набор уровней, при этом каждый уровень имеет определенную ответственность и взаимодействует с уровнями выше и ниже него. Основная идея многоуровневой архитектуры состоит в том, чтобы разделить задачи системы на отдельные и независимые уровни, сделав код более модульным, более простым для понимания, тестирования и модификации. 285 | 286 | Существует несколько типов многоуровневых архитектур, но наиболее распространенной является трехуровневая архитектура, состоящая из: 287 | 288 | * Уровень представления (Presentation Layer) 289 | * Уровень бизнес-логики (Business Layer) 290 | * Уровень доступа к данным (Data Access Layer) 291 | 292 | Полезные ссылки: 293 | 294 | * [Software Architecture Patterns — Layered Architecture](https://priyalwalpita.medium.com/software-architecture-patterns-layered-architecture-a3b89b71a057) 295 | * [5 Primary Layers in Software Architecture?](https://www.indeed.com/career-advice/career-development/what-are-the-layers-in-software-architecture) 296 | 297 | ##### Единый язык 298 | 299 | Единый язык — это специфический словарь и набор понятий, используемых для описания и общения в определенной области знаний или бизнеса. При разработке программного обеспечения единый язык язык используется для моделирования объектов и понятий в конкретной предметной области, а также для фиксации взаимосвязей и ограничений между ними. 300 | 301 | Единый язык используется для обеспечения единообразного понимания проблемной области всеми заинтересованными сторонами, включая разработчиков, бизнес-аналитиков и экспертов в предметной области. Он также применяется, чтобы гарантировать, что программная система точно отражает существующую в реальном мире проблему, которую она призвана решать. 302 | 303 | Полезные ссылки: 304 | 305 | * [Overview of Domain-specific language](https://en.wikipedia.org/wiki/Domain-specific_language) 306 | * [What are Domain Languages (DSLs)?](https://www.jetbrains.com/mps/concepts/domain-specific-languages/) 307 | 308 | ##### Инварианты класса 309 | 310 | Инвариант класса — это набор условий, которые должны выполняться для любого объекта класса в любой момент времени. В объектно-ориентированном программировании (ООП) инварианты классов используются для определения допустимых состояний объекта и гарантирования того, чтобы объект всегда будет оставаться в допустимом состоянии. 311 | 312 | Инварианты класса обычно определяются в конструкторе класса и задаются с помощью закрытых методов и атрибутов, которые используются для проверки состояния объекта. Они также проверяются в методах класса до и после любой операции, которая может изменить состояние объекта. 313 | 314 | Полезные ссылки: 315 | 316 | * [Overview of Class invariant](https://en.wikipedia.org/wiki/Class_invariant) 317 | * [Википедия - Инвариант класса](https://ru.wikipedia.org/wiki/%D0%98%D0%BD%D0%B2%D0%B0%D1%80%D0%B8%D0%B0%D0%BD%D1%82_%D0%BA%D0%BB%D0%B0%D1%81%D1%81%D0%B0) 318 | * [The concept of class invariant in object-oriented programming](https://arxiv.org/abs/2109.06557) 319 | 320 | #### Особенности парадигмы 321 | 322 | Объектно-ориентированное программирование (ООП) — это парадигма программирования, основанная на понятии «объектов», которые являются экземплярами класса. ООП имеет несколько ключевых особенностей, которые отличают его от других парадигм программирования: 323 | 324 | * Инкапсуляция 325 | * Наследование 326 | * Полиморфизм 327 | * Абстракция 328 | * Классы 329 | * Объекты 330 | * Интерфейсы 331 | * Динамическое (позднее) связывание 332 | * Передача сообщений 333 | 334 | Полезные ссылки: 335 | 336 | * [Overview of Object-Oriented Paradigm](https://www.tutorialspoint.com/software_architecture_design/object_oriented_paradigm.htm) 337 | 338 | ##### Абстрактные классы 339 | 340 | Абстрактный класс — это класс в объектно-ориентированном программировании (ООП), который не может быть создан. Вместо этого он служит шаблоном или образцом для наследования другими классами. Абстрактный класс может содержать как абстрактные, так и неабстрактные методы (абстрактные методы — это методы, которые не имеют реализации, они просто содержат сигнатуру). 341 | 342 | Абстрактные классы используются для предоставления общего интерфейса и реализации для группы связанных классов. Они также применяются для определения общего поведения, которое должно быть реализовано всеми подклассами. Подкласс, который наследуется от абстрактного класса, называется реальным классом, и он должен предоставлять реализацию для всех абстрактных методов, объявленных в родительском классе. 343 | 344 | Полезные ссылки: 345 | 346 | * [What is an Abstract Class in Object Oriented Programming](https://computinglearner.com/abstract-class-in-object-oriented-programming/) 347 | 348 | ##### Реальные классы 349 | 350 | Реальный класс — это класс в объектно-ориентированном программировании (ООП), который может быть создан, то есть из него могут быть созданы объекты. Реальный класс — это класс, который обеспечивает реализацию всех абстрактных методов, объявленных в его родительском классе, если он наследуется от абстрактного класса. Реальный класс также может быть классом, который не наследуется от абстрактного класса, в этом случае в нём реализованы все его методы. 351 | 352 | Реальные классы используются для предоставления конкретных деталей реализации для группы связанных классов, которые наследуются от общего абстрактного класса. Они также используются для задания уникального поведения для определенного класса. Реальный класс может иметь свои собственные методы и переменные, а также может переопределять методы своего родительского класса. 353 | 354 | Полезные ссылки: 355 | 356 | * [Concrete class in Java](https://www.geeksforgeeks.org/concrete-class-in-java/) 357 | 358 | ##### Область видимости 359 | 360 | Область видимости относится к доступности или видимости переменных, функций и других элементов в программе в зависимости от контекста, в котором они определены. В объектно-ориентированном программировании (ООП) область видимости контролируется с помощью модификаторов доступа, таких как "public" («публичный», «открытый», «общедоступный»), "private" («приватный», «закрытый», «частный») и "protected" («защищённый»). 361 | 362 | Общедоступный: к общедоступному элементу можно получить доступ из любой точки программы, как внутри класса, так и за его пределами. 363 | 364 | Закрытый: доступ к закрытому элементу возможен только внутри класса, в котором он определен. Он недоступен для других классов, даже если они наследуются от класса. 365 | 366 | Защищенный: доступ к защищенному элементу возможен только внутри класса и его подклассов. 367 | 368 | Существуют и другие разновидности области видимости в зависимости от языка программирования, но эти являются наиболее распространенными. 369 | 370 | Полезные ссылки: 371 | 372 | * [Википедия — Область видимости](https://ru.wikipedia.org/wiki/%D0%9E%D0%B1%D0%BB%D0%B0%D1%81%D1%82%D1%8C_%D0%B2%D0%B8%D0%B4%D0%B8%D0%BC%D0%BE%D1%81%D1%82%D0%B8) 373 | 374 | ##### Интерфейсы 375 | 376 | В объектно-ориентированном программировании (ООП) интерфейс — это контракт или набор методов, которые должен реализовать класс. Он определяет общий набор методов, которые должен иметь класс, но не предоставляет никаких подробностей реализации. Интерфейс может включать как сигнатуры методов, так и константы. 377 | 378 | Интерфейсы используются для определения общего поведения для группы связанных классов и для обеспечения полиморфизма в случае с объектами разных классов. Класс, удовлетворяющий интерфейсу, должен осуществлять реализацию всех методов, объявленных в интерфейсе. Класс может реализовывать несколько интерфейсов, но может наследоваться только от одного базового класса. 379 | 380 | Полезные ссылки: 381 | 382 | * [Fundamental concepts: What’s an Interface?](https://www.youtube.com/watch?v=o1jBgdhQsGo) 383 | 384 | #### Основные понятия 385 | 386 | Существует несколько основных понятий, которые считаются фундаментальными для объектно-ориентированного программирования (ООП). Эти понятия включают в себя: 387 | 388 | * Инкапсуляция: Практика помещения внутренних данных и поведения объекта в определенный интерфейс и сокрытие деталей реализации от внешнего мира. 389 | * Наследование: способность нового класса наследовать свойства и методы существующего класса, что позволяет повторно использовать код и обеспечивает иерархическую организацию классов. 390 | * Полиморфизм: способность рассматривать объекты разных классов как объекты общего родительского класса, что позволяет писать более обобщённый и универсальный код. 391 | * Абстракция: процесс сокрытия деталей реализации объекта и раскрытия только его основных функций, что снижает сложность и улучшает модульность кода. 392 | * Классы: шаблон для создания объектов, которые имеют как данные (атрибуты), так и поведение (методы). 393 | * Объекты: Экземпляры класса, имеющие собственное уникальное состояние и поведение. 394 | 395 | Полезные ссылки: 396 | 397 | * [Principles of Object-Oriented Programming](https://khalilstemmler.com/articles/object-oriented/programming/4-principles/) 398 | * [What are four basic principles of OOP?](https://medium.com/@cancerian0684/what-are-four-basic-principles-of-object-oriented-programming-645af8b43727) 399 | 400 | ##### Наследование 401 | 402 | Наследование — это фундаментальное понятие объектно-ориентированного программирования (ООП), которое позволяет новому классу наследовать свойства и методы существующего класса. Класс, от которого наследуется, называется родительским или суперклассом, а класс, который наследует, называется дочерним или подклассом. Наследование позволяет повторно использовать код и обеспечивает иерархическую организацию классов, при которой дочерний класс может наследовать свойства и методы своего родительского класса и потенциально добавлять или переопределять их. Основное преимущество наследования заключается в том, что оно позволяет реализовать понятный и организованный способ повторного использования кода и пользоваться единожды написанным функционалом как в родительском, так и в дочерних классах. 403 | 404 | Полезные ссылки: 405 | 406 | * [What is inheritance in programming?](https://www.youtube.com/watch?v=ajOYOxCanhE) 407 | * [Overview of Inheritance (object-oriented programming)](https://en.wikipedia.org/wiki/Inheritance_(object-oriented_programming)) 408 | 409 | ##### Полиморфизм 410 | 411 | Полиморфизм — это понятие объектно-ориентированного программирования (ООП), которая позволяет рассматривать объекты разных классов как объекты общего родительского класса. Это достигается путем определения общего интерфейса для всех классов, которые необходимо рассматривать полиморфно. Слово «полиморфизм» («многообразие форм», «многообразный») происходит от греческих слов «поли» (πολύ), что означает «много» и «морф» (μορφ) — «форма». 412 | 413 | Существует два типа полиморфизма: 414 | 415 | * Полиморфизм времени компиляции (также называемый статическим полиморфизмом или ранним связыванием) возникает, когда тип объекта, с которым будут проводиться определенные действия, определяется во время компиляции. Это достигается за счет перегрузки методов, которая позволяет нескольким методам иметь одно и то же имя, но разные параметры в одном классе. 416 | * Полиморфизм времени выполнения (также называемый динамическим полиморфизмом или поздним связыванием) возникает, когда тип объекта определяется во время выполнения. Это достигается за счет переопределения методов, что позволяет дочернему классу предоставлять конкретную реализацию метода, который уже определен в его родительском классе. 417 | 418 | Полезные ссылки: 419 | 420 | * [Overview of Polymorphism in programming](https://www.bmc.com/blogs/polymorphism-programming/) 421 | * [What is polymorphism in programming?](https://www.youtube.com/watch?v=tIWm3I_Zu7I) 422 | 423 | ##### Абстракция 424 | 425 | Абстракция — это понятие объектно-ориентированного программирования (ООП), которое относится к процессу сокрытия деталей реализации объекта и раскрытию только его основных функций. Это позволяет использовать объекты без необходимости понимать всю сложность их внутренней структуры и поведения. 426 | 427 | Существует два типа абстракции: 428 | 429 | * Абстракция данных: относится к сокрытию внутреннего представления данных и выдаче их в упрощенном виде с помощью набора четко определенных интерфейсов. 430 | * Абстракция поведения: относится к сокрытию внутреннего поведения объекта и реализация в упрощенной форме его возможностей с помощью набора четко определенных интерфейсов. 431 | 432 | Полезные ссылки: 433 | 434 | * [Tutorial - Abstraction](https://www.youtube.com/watch?v=OF55HZPE7lQ) 435 | * [Абстракция данных](https://ru.wikipedia.org/wiki/%D0%90%D0%B1%D1%81%D1%82%D1%80%D0%B0%D0%BA%D1%86%D0%B8%D1%8F_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85) 436 | 437 | ##### Инкапсуляция 438 | 439 | Инкапсуляция — это понятие объектно-ориентированного программирования (ООП), которое относится к практике помещения внутренних данных и поведения объекта в определенный интерфейс и сокрытия деталей реализации от внешнего мира. Это одна из фундаментальных понятий ООП, тесно связанная с принципами сокрытия данных и сокрытия информации. 440 | 441 | Инкапсуляция достигается за счет использования модификаторов доступа (таких как "public", "private" и "protected") для управления областью видимости и доступностью данных и методов объекта. Например, атрибуты класса могут быть объявлены как закрытые (приватные, "private"), т. е. доступ к ним возможен только с помощью методов внутри класса, а методы могут быть объявлены как открытые (публичные, "public"), т. е. их можно вызывать из любой части кода, имеющей ссылку на объект. 442 | 443 | Полезные ссылки: 444 | 445 | * [Overview of Encapsulation](https://en.wikipedia.org/wiki/Encapsulation_(computer_programming)) 446 | * [Википедия - Инкапсуляция (программирование)](https://ru.wikipedia.org/wiki/%D0%98%D0%BD%D0%BA%D0%B0%D0%BF%D1%81%D1%83%D0%BB%D1%8F%D1%86%D0%B8%D1%8F_(%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5)) 447 | * [Tutorial - What is encapsulation in programming?](https://www.youtube.com/watch?v=sNKKxc4QHqA) 448 | 449 | ## Принципы проектирования программного обеспечения 450 | 451 | Существует множество принципов проектирования программного обеспечения, направленных на то, чтобы разрабатываемое программное обеспечение было легко понять, поддерживать и расширять. Некоторые из наиболее распространенных включают в себя: 452 | 453 | * Принципы SOLID (принцип единой ответственности, принцип открытости/закрытости, принцип подстановки Лисков, принцип разделения интерфейсов и принцип инверсии зависимостей) 454 | * DRY (Не повторяйтесь) 455 | * YAGNI (Вам это никогда не понадобится) 456 | * KISS (Чем проще, тем лучше) 457 | * LoD (Закон Деметры) 458 | * Используйте композицию, а не наследование 459 | * Инкапсулируйте то, что изменяется 460 | * Голливудский принцип 461 | * Пишите программы, основываясь на абстракциях 462 | 463 | Следуя этим принципам проектирования, программное обеспечение может быть разработано таким образом, чтобы его было легко понять, поддерживать и расширять, а также оно было менее подвержено ошибкам. 464 | 465 | Полезные ссылки: 466 | 467 | * [Principles of Software Design](https://www.geeksforgeeks.org/principles-of-software-design/) 468 | * [Software Design Principles For Beginners](https://www.youtube.com/watch?v=60EqoRcanpo) 469 | 470 | ### Используйте композицию, а не наследование 471 | 472 | Композиция вместо наследования — это принцип программирования, который предполагает, что лучше использовать композицию, механизм сборки объектов, для создания сложных объектов, а не использовать наследование, которое представляет собой механизм создания новых классов на основе существующих. 473 | 474 | Наследование — это мощный механизм для создания повторно используемого кода, но он также может привести к возникновению сильно связанного кода, который трудно поддерживать. Это связано с тем, что унаследованные классы сильно связаны со своими родительскими классами, и любые изменения, внесенные в родительский класс, повлияют на все его дочерние классы. Это затрудняет изменение или расширение кода без влияния на всю иерархию классов. 475 | 476 | Полезные ссылки: 477 | 478 | * [Tutorial - Composition over Inheritance](https://www.youtube.com/watch?v=wfMtDGfHWpA) 479 | * [Overview of Composition over Inheritance](https://en.wikipedia.org/wiki/Composition_over_inheritance) 480 | 481 | ### Инкапсулируйте то, что изменяется 482 | 483 | Инкапсулируйте то, что изменяется — это принцип программирования, который предполагает, что код должен быть организован таким образом, чтобы части, которые могут измениться в будущем, были изолированы от частей, которые вряд ли изменятся. Это достигается путем создания интерфейсов и классов, которые отделяют изменяющиеся части кода от не меняющихся. 484 | 485 | Инкапсуляция того, что меняется обеспечивает бóльшую гибкость кода. Когда необходимы изменения, их можно внести в инкапсулированные части, не затрагивая остальную часть кода. Это облегчает понимание, тестирование и сопровождение кода. 486 | 487 | Полезные ссылки: 488 | 489 | * [Почему нужно инкапсулировать то, что изменяется?](https://ru.stackoverflow.com/questions/499882/%D0%9F%D0%BE%D1%87%D0%B5%D0%BC%D1%83-%D0%BD%D1%83%D0%B6%D0%BD%D0%BE-%D0%B8%D0%BD%D0%BA%D0%B0%D0%BF%D1%81%D1%83%D0%BB%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D1%82%D1%8C-%D1%82%D0%BE-%D1%87%D1%82%D0%BE-%D0%B8%D0%B7%D0%BC%D0%B5%D0%BD%D1%8F%D0%B5%D1%82%D1%81%D1%8F) 490 | * [What does it mean when one says “Encapsulate what varies”?](https://softwareengineering.stackexchange.com/questions/337413/what-does-it-mean-when-one-says-encapsulate-what-varies) 491 | * [Overview of Encapsulate What Varies](https://bootcamp.uxdesign.cc/software-design-principles-every-developers-should-know-23d24735518e) 492 | 493 | ### Пишите программы, основываясь на абстракциях 494 | 495 | **Программируйте на уровне интерфейсов, а не реализации** 496 | 497 | Программирование на основе абстракций — это принцип программирования, который предполагает, что код должен быть написан таким образом, чтобы он не был привязан к конкретным реализациям, а к абстракциям. Это достигается путем определения интерфейсов или абстрактных классов, которые задают поведение группы связанных классов без указания их реализации. 498 | 499 | Программирование на основе абстракций обеспечивает бóльшую гибкость кода. Когда необходимы изменения, они могут быть внесены в реализацию абстракций, не затрагивая код, который их использует. Это облегчает понимание, тестирование и сопровождение кода. 500 | 501 | Полезные ссылки: 502 | 503 | * [What is Abstraction in Programming – And Why is it Useful?](https://www.freecodecamp.org/news/what-is-abstraction-in-programming/) 504 | * [Overview of Abstraction principle](https://en.wikipedia.org/wiki/Abstraction_principle_(computer_programming)) 505 | 506 | ### Голливудский принцип 507 | 508 | Голливудский принцип — это принцип разработки программного обеспечения, который гласит: «Не звоните нам, мы сами вам позвоним». Он предполагает, что высокоуровневые (интерфейсы), а не низкоуровневые компоненты (реализации) должны определять порядок выполнения кода в приложении. 509 | 510 | Этот принцип часто используется в контексте инверсии управления (Inversion of Control, IoC) и внедрения зависимостей. Обычно при разработке программного обеспечения низкоуровневые компоненты отвечают за создание и управление высокоуровневыми компонентами, от которых они зависят. В IoC высокоуровневые компоненты задают порядок выполнения кода, а низкоуровневые компоненты создаются и управляются с помощью отдельного механизма. 511 | 512 | Полезные ссылки: 513 | 514 | * [Tutorial - Hollywood Principle](https://www.youtube.com/watch?v=lRuygpsXE5s) 515 | 516 | ### SOLID 517 | 518 | SOLID — это аббревиатура, обозначающая пять принципов объектно-ориентированной разработки программного обеспечения, впервые представленных Робертом С. Мартином в начале 2000-х годов. А именно: 519 | 520 | * Принцип единой ответственности (**S**RP, Single Responsibility Principle) 521 | * Принцип открытости/закрытости (**O**CP, Open/Closed Principle) 522 | * Принцип подстановки Лисков (**L**SP, Liskov Substitution Principle) 523 | * Принцип разделения интерфейсов (**I**SP, Interface Segregation Principle) 524 | * Принцип инверсии зависимостей (**D**IP, Dependency Inversion Principle) 525 | 526 | Полезные ссылки: 527 | 528 | * [Get Started with SOLID](https://www.bmc.com/blogs/solid-design-principles/) 529 | * [SOLID Principles](https://khalilstemmler.com/articles/tags/solid/) 530 | * [Tutorial - What are SOLID principle?](https://www.youtube.com/watch?v=aUCo5cy32kE) 531 | 532 | ### DRY 533 | 534 | DRY (Don’t Repeat Yourself, «Не повторяйтесь») — это принцип разработки программного обеспечения, который предполагает, что код не должен иметь повторяющихся частей. Идея состоит в том, чтобы максимально упростить кодовую базу, устранив избыточность и дублирование. Цель заключается в том, чтобы уменьшить сложность и улучшить удобство сопровождения, гарантируя, что каждая часть знаний выражается в системе единым и недвусмысленным способом. 535 | 536 | Принцип DRY тесно связан с принципом единой ответственности (SRP) и принципом открытости/закрытости (OCP), которые являются частью принципов SOLID. Принцип DRY пытается уменьшить количество повторяющегося кода за счет создания абстракций, которые можно повторно использовать в системе. 537 | 538 | Полезные ссылки: 539 | 540 | * [What is DRY in programming?](https://www.youtube.com/watch?v=Rv3RIc_ziOY) 541 | * [Overview of Don’t repeat yourself (DRY)](https://en.wikipedia.org/wiki/Don%27t_repeat_yourself) 542 | 543 | ### YAGNI 544 | 545 | YAGNI (You Ain’t Gonna Need It, «Вам это никогда не понадобится») — это принцип разработки программного обеспечения, который предполагает, что разработчики не должны добавлять функциональные возможности в кодовую базу, если в этом нет немедленной необходимости. Идея состоит в том, чтобы избежать создания ненужной сложности в кодовой базе, добавляя только тот функционал, который действительно необходим. 546 | 547 | Принцип YAGNI тесно связан с принципом единой ответственности (SRP) и принципом открытости-закрытости (OCP), которые являются частью принципов SOLID. YAGNI стремится максимально упростить кодовую базу, избегая создания ненужных абстракций и функциональных возможностей. 548 | 549 | Полезные ссылки: 550 | 551 | * [YAGNI (You Aren’t Gonna Need It) Principle Helps in Efficiency](https://builtin.com/software-engineering-perspectives/yagni) 552 | * [What is YAGNI coding rule, and Why it helps?](https://www.youtube.com/watch?v=2vys1q1dKc4) 553 | 554 | -------------------------------------------------------------------------------------------------------------------------------- 555 | 556 | 1. Фримен Э., Робсон Э., Сьерра К., Бейтс Б. Head First. Паттерны проектирования. Обновленное юбилейное издание. — СПб.: Питер, 2018. — 557 | 656 с.: ил. — (Серия «Head First O’Reilly»). 558 | 559 | ## Шаблоны проектирования 560 | 561 | Шаблоны проектирования — это обобщённые решения часто встречающихся проблем, возникающих при разработке программного обеспечения. Они описывают и предоставляют проверенные решения характерных проблем проектирования, а также снабжают словарём обобщенных терминов для проектирования. Они не относятся к какому-либо конкретному языку программирования или технологии, а скорее описывают проблему и решение таким образом, чтобы их можно было применять во многих различных контекстах. 562 | 563 | Существует несколько различных шаблонов проектирования, а именно: 564 | 565 | * Порождающие шаблоны 566 | * Структурные шаблоны 567 | * Поведенческие шаблоны 568 | * Архитектурные шаблоны 569 | 570 | Полезные ссылки: 571 | 572 | * [What Are Design Patterns?](https://www.youtube.com/watch?v=BWprw8UHIzA) 573 | * [Overview - Software Design Pattern](https://en.wikipedia.org/wiki/Software_design_pattern) 574 | * [Шаблон проектирования](https://ru.wikipedia.org/wiki/%D0%A8%D0%B0%D0%B1%D0%BB%D0%BE%D0%BD_%D0%BF%D1%80%D0%BE%D0%B5%D0%BA%D1%82%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F) 575 | 576 | ### GoF шаблоны проектирования 577 | 578 | Шаблоны проектирования «Банда четырех» (GoF, Gang of Four) — это набор шаблонов проектирования для разработки объектно-ориентированного программного обеспечения, которые впервые были описаны в книге «Паттерны объектно-ориентированного проектирования» Эриха Гаммы, Ричарда Хелма, Ральфа Джонсона, и Джон Влиссидес (также известные как «Банда четырех»). 579 | 580 | Шаблоны проектирования GoF делятся на три категории: порождающие, структурные и поведенческие. 581 | 582 | * Порождающие шаблоны 583 | * Структурные шаблоны 584 | * Поведенческие шаблоны 585 | 586 | Полезные ссылки: 587 | 588 | * [Gangs of Four (GoF) Design Patterns](https://www.digitalocean.com/community/tutorials/gangs-of-four-gof-design-patterns) 589 | * [Tutorial - Builder Pattern (Gang of Four Design Patterns Series)](https://www.youtube.com/watch?v=_sa2WlAFWQos) 590 | * Гамма Э., Хелм Р., Джонсон Р., Влиссидес Дж. Паттерны объектно-ориентированного проектирования. — СПб.: Питер, 2020. — 448 с.: ил. 591 | * Мэтт Зандстра. PHP 8: объекты, шаблоны и методики программирования, 6-е издание, 2021. 592 | 593 | ### PoSA шаблоны 594 | 595 | POSA (Patterns of Scalable and Adaptable Software Architecture, Шаблоны масштабируемой и адаптируемой архитектуры программного обеспечения) — это набор шаблонов проектирования для разработки программных систем, которые могут масштабироваться и адаптироваться к изменяющимся требованиям. Эти шаблоны были впервые описаны в книге «Шаблоны масштабируемых, надежных сервисов» Кевина Хоффмана. 596 | 597 | Шаблоны POSA делятся на четыре категории: 598 | 599 | * Разделяющие шаблоны 600 | * Размещающие шаблоны 601 | * Маршрутизирующие шаблоны 602 | * Объединяющие шаблоны 603 | 604 | Полезные ссылки: 605 | 606 | * [POSA Pattern Examples](https://www.youtube.com/watch?v=iYNa_KcWxCU) 607 | * [Overview of Pattern-Oriented Software Architecture](https://en.wikipedia.org/wiki/Pattern-Oriented_Software_Architecture) 608 | * F. Buschmann, R. Meunier, H. Rohnert, P. Sommerlad, M. Stal: Pattern-Oriented Software Architecture — A System of Patterns, John Wiley 609 | and Sons, 2013. 610 | * Brendan Burns, Designing Distributed Systems: Patterns and Paradigms for Scalable, Reliable Services, O'Reilly Media, 2018. 611 | * [Pattern-Oriented Software Architecture](http://www.dre.vanderbilt.edu/~schmidt/POSA-tutorial.pdf) 612 | 613 | ## Архитектурные принципы 614 | 615 | Архитектурные принципы относятся к набору директив или правил, которые используются в качестве ориентиров при проектировании и разработке архитектуры программного обеспечения. Эти принципы предназначены для того, чтобы полученная архитектура была удобной в сопровождении, масштабируемой, простой для понимания и изменения. К наиболее часто встречающимся архитектурным принципам относят следующие: разделение ответственности, модульность, слабую связанность и сильную связность. Кроме того, архитектурные принципы часто применяются в сочетании с шаблонами проектирования, которые представляют собой решения характерных проблем при разработке программного обеспечения с возможностью многократного использования. 616 | 617 | Полезные ссылки: 618 | 619 | * [Intro to Architectural Principles](https://learn.microsoft.com/en-us/dotnet/architecture/modern-web-apps-azure/architectural-principles) 620 | * [Principles of Software Design](https://www.youtube.com/watch?v=TO9igqkPtfc) 621 | 622 | ### Компонентно-ориентированное программирование 623 | 624 | Компонентно-ориентированный принцип рекомендует проектировать и реализовывать программные компоненты в виде модулей, которые можно многократно использовать и так, чтобы они были простыми для понимания, тестирования и обслуживания. Некоторые из ключевых принципов компонентно-ориентированного программирования в архитектуре программного обеспечения включают в себя: 625 | 626 | * Сильная связность 627 | * Слабая связанность 628 | * Разделение ответственности 629 | * Проектирование на основе интерфейсов 630 | * Возможность повторного использования 631 | * Тестируемость 632 | * Модульность 633 | * Совместимость 634 | 635 | Следуя этим принципам, программное обеспечение может быть разработано так, чтобы его было легко понять, поддерживать и расширять, и оно было бы менее подвержено ошибкам. Это также обеспечивает более эффективное повторное использование кода (компоненты можно повторно использовать в разных контекстах), упрощает его тестирование и изменение. 636 | 637 | Полезные ссылки: 638 | 639 | * [Component-Based Architecture](https://www.tutorialspoint.com/software_architecture_design/component_based_architecture.htm) 640 | 641 | ### Стратегия vs детали реализации 642 | 643 | В архитектуре программного обеспечения **стратегия** - это высокоуровневые решения, а **детали** - это низкоуровневая реализация. 644 | 645 | **Стратегия** - это высокоуровневые решения, которые определяют общее поведение и структуру системы. Эти решения включают в себя такие вещи, как общая архитектура, интерфейс системы, основные компоненты и их взаимодействие. Стратегические решения часто принимаются архитекторами и проектировщиками, и они задают общее направление для системы. 646 | 647 | **Детали** - это низкоуровневые реализации, которые необходимы для осуществления стратегических решений. К ним относятся определённые алгоритмы, структуры данных и код, из которых состоят компоненты системы. Детали часто реализуются разработчиками и отвечают за фактическое функционирование системы. 648 | 649 | Полезные ссылки: 650 | 651 | * G6: Код на неверном уровне абстракции. Мартин Р. Чистый код: создание, анализ и рефакторинг. Библиотека программиста. — СПб.: Питер, 2013. — 464 с.: ил. — (Серия «Библиотека программиста»). 652 | 653 | ### Связанность (coupling) и связность (cohesion) 654 | 655 | Связанность (coupling) и связность (cohesion) — это два принципа в архитектуре программного обеспечения, которые используются для измерения степени взаимозависимости между компонентами в системе. 656 | 657 | Связанность (coupling) относится к степени, зависимости одного компонента от другого. Сильная связанность означает, что изменение в одном компоненте, вероятно, повлияет на другие компоненты, что усложнит понимание, тестирование и обслуживание системы. Слабая связанность, напротив, означает, что изменения в одном компоненте оказывают минимальное влияние на другие компоненты, что делает систему более модульной и более простой для понимания, тестирования и обслуживания. 658 | 659 | Связность (cohesion), в свою очередь, определяет насколько связаны друг с другом задачи, выполняемые некоторым конкретным компонентом. Сильная связность означает, что компонент имеет одну четко определенную цель и что весь его функционал и данные связаны с этой целью. Слабая связность, с другой стороны, означает, что компонент имеет несколько несвязанных между собой обязанностей, что затрудняет его понимание, тестирование и поддержку. 660 | 661 | Полезные ссылки: 662 | 663 | * [Low Coupling и High Cohesion](https://medium.com/german-gorelkin/low-coupling-high-cohesion-d36369fb1be9) 664 | * [Зацепление (программирование)](https://ru.wikipedia.org/wiki/%D0%97%D0%B0%D1%86%D0%B5%D0%BF%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_(%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5)) 665 | * [Связность (программирование)](https://ru.wikipedia.org/wiki/%D0%A1%D0%B2%D1%8F%D0%B7%D0%BD%D0%BE%D1%81%D1%82%D1%8C_(%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5)) 666 | * [Cohesion and Coupling in Software Engineering](https://www.youtube.com/watch?v=NweTzHYBgYU) 667 | * [Overview of Coupling and Cohesion](https://www.geeksforgeeks.org/software-engineering-coupling-and-cohesion/) 668 | 669 | ### Границы частей приложения 670 | 671 | В архитектуре программного обеспечения границы частей приложения относятся к интерфейсам или точкам разделения между различными компонентами или системами. Эти границы могут быть физическими, например, между различными микросервисами в распределенной системе, или логическими, например, между различными уровнями в приложении. 672 | 673 | Границы важны, потому что они определяют точки взаимодействия между различными компонентами или системами и задают, как эти компоненты или системы будут взаимодействовать друг с другом. Определение четких границ облегчает понимание, тестирование и обслуживание системы, поскольку взаимодействие между компонентами или системами четко определено и о них легко рассуждать. 674 | 675 | Полезные ссылки: 676 | 677 | * [Boundaries in Software Architecture](https://www.open.edu/openlearn/science-maths-technology/approaches-software-development/content-section-1.1.4) 678 | 679 | ## Архитектурные стили 680 | 681 | Архитектурные стили в программном обеспечении относятся к общему замыслу и организации программной системы, а также к принципам и шаблонам, которые определяют направление проектирования. Эти стили обеспечивают общую основу для проектирования системы и могут использоваться для обеспечения хорошей структуры, удобства обслуживания и масштабируемости системы. 682 | 683 | Некоторыми распространенными архитектурными стилями в программном обеспечении являются: 684 | 685 | * Микросервисы: когда система построена как набор небольших, независимых и слабо связанных сервисов. 686 | * Событийно-ориентированный: когда система реагирует на определённые события, которые происходят, а не постоянно опрашивается на наличие изменений. 687 | * Многоуровневый: система разделена на ряд уровней, каждый из которых имеет определенную ответственность и взаимодействует с другими уровнями через четко определенные интерфейсы. 688 | * Сервис-ориентированный: система построена как набор сервисов, к которым можно получить доступ через сеть. 689 | * Ориентированность на данные: система ориентирована на хранение, поиск и манипулирование данными, а не на их обработку. 690 | * Компонентно-ориентированный: когда система состоит из повторно используемых и независимых программных компонентов. 691 | * Предметно-ориентированный: система организована вокруг смыслового ядра и сущностей бизнеса. 692 | 693 | Полезные ссылки: 694 | 695 | * [What is Software Architecture & Styles?](https://study.com/academy/lesson/software-architecture-styles-patterns-components.html) 696 | * [Types of Architectural Styles in Software Engineering](https://www.youtube.com/watch?v=2Pp0BcXN9YY) 697 | * [10 Architecture Patterns Used In Enterprise Software Development Today](https://www.youtube.com/watch?v=brt3ao8bvqy) 698 | 699 | ### по типу обмена сообщениями 700 | 701 | Обмен сообщениями является ключевым понятием в нескольких архитектурных стилях, включая событийно-ориентированную архитектуру (EDA), микросервисы и архитектуру, управляемую сообщениями (MDA). 702 | 703 | * Событийно-ориентированная архитектура (EDA) 704 | * Микросервисы 705 | * Архитектура, управляемая сообщениями (MDA) 706 | 707 | Как правило, обмен сообщениями — это мощная концепция, позволяющая разделить и масштабировать системы, и она используется в различных архитектурных стилях для повышения гибкости и масштабируемости системы за счет ослабления связи между компонентами и упрощения добавления новых функций или изменения существующих. 708 | 709 | Полезные ссылки: 710 | 711 | * [Architectural Styles in Software Engineering](https://shapingsoftware.com/2009/02/09/architectural-styles/) 712 | * [Architectural Messaging Patterns](https://www.redhat.com/architect/architectural-messaging-patterns) 713 | 714 | #### событийно-ориентированная 715 | 716 | Событийно-ориентированная архитектура (EDA) — это шаблон проектирования программного обеспечения, в котором система реагирует на определенные происходящие события, а не постоянно опрашивается на наличие изменений. В EDA события — это сообщения, которые асинхронно отправляются компонентам, а компоненты реагируют на интересующие их события. 717 | 718 | Основное преимущество использования EDA заключается в том, что она позволяет четко разделить ответственность между компонентами и может улучшить масштабируемость и отказоустойчивость системы. Кроме того, она допускает слабую связь между компонентами, т. е. компоненты не знают о существовании друг друга и могут разрабатываться, развертываться и масштабироваться независимо. 719 | 720 | Полезные ссылки: 721 | 722 | * [Overview of Event-driven programming](https://en.wikipedia.org/wiki/Event-driven_programming) 723 | * [What is event-driven architecture?](https://www.redhat.com/en/topics/integration/what-is-event-driven-architecture) 724 | 725 | #### издатель/подписчик 726 | 727 | Шаблон издатель/подписчик — это шаблон обмена сообщениями, в котором издатель отправляет сообщение в определенную катетогию, и любое количество подписчиков может подписаться на эту категорию, чтобы получить сообщение. Шаблон издатель/подписчик также известен как «шаблон наблюдателя» и представляет собой способ реализации взаимодействия между различными частями приложения так, чтобы они не были связаны. 728 | 729 | Основное преимущество использования шаблона издатель/подписчик заключается в том, что он позволяет четко разделить обязанности между издателем и подписчиками и может повысить гибкость и масштабируемость системы. Кроме того, он допускает слабую связь между компонентами, т. е. издатель и подписчики не знают о существовании друг друга и могут разрабатываться, развертываться и масштабироваться независимо. 730 | 731 | Полезные ссылки: 732 | 733 | * [Publish-Subscribe Architecture (Explained by Example)](https://www.youtube.com/watch?v=O1PgqUqZKTA) 734 | * [Tutorial - Publish–subscribe pattern](https://en.wikipedia.org/wiki/Publish%E2%80%93subscribe_pattern) 735 | 736 | ### по способу взаимодействия в распределенной сети 737 | 738 | Распределенные системы - это способ разработки и организации программных компонентов, при которой они распределены по нескольким устройствам или локациям, подключены через сеть и работают вместе для достижения общей цели. Основная проблема при проектировании распределенных систем заключается в том, чтобы справиться со сложностью, присущей распределению компонентов и обмену данными между ними, и для улучшения масштабируемости, отказоустойчивости и производительности требуются такие методы, как балансировка нагрузки, репликация и партицирование/секционирование. Кроме того, безопасность и координация также являются важными аспектами распределенных систем. 739 | 740 | Полезные ссылки: 741 | 742 | * [Overview of Distributed Architecture](https://www.tutorialspoint.com/software_architecture_design/distributed_architecture.htm) 743 | 744 | #### клиент-сервер 745 | 746 | Архитектура клиент-сервер — это распространенный архитектурный шаблон, используемый в распределенных системах, где клиент (или несколько клиентов) отправляет запросы на сервер, а сервер отвечает на эти запросы. Клиент и сервер — это отдельные субъекты, которые обмениваются данными по сети, такой как Интернет или локальная сеть. 747 | 748 | Клиент отвечает за представление пользовательского интерфейса и обработку пользовательского ввода, а сервер — за обработку запросов и возврат соответствующего ответа. Сервер также может выполнять такие задачи, как хранение данных, безопасность и бизнес-логика. 749 | 750 | Полезные ссылки: 751 | 752 | * [Intro to Client-server Architecture](https://cs.uwaterloo.ca/~m2nagapp/courses/CS446/1195/Arch_Design_Activity/ClientServer.pdf) 753 | 754 | #### одноранговое, децентрализованное или пиринговое (peer-to-peer, P2P) 755 | 756 | Одноранговая (P2P) архитектура — это архитектура распределенных вычислений, в которой каждый узел (peer, пир) в сети ведёт себя как клиент и сервер. В архитектуре P2P нет центрального органа или сервера, который управляет сетью, и каждый узел напрямую взаимодействует с другими узлами для обмена информацией, совместного использования ресурсов и выполнения вычислений. 757 | 758 | Основное преимущество использования P2P архитектуры заключается в том, что она позволяет создать более децентрализованную и отказоустойчивую систему. Поскольку нет центрального органа, нет единой точки отказа, и сеть может продолжать функционировать, даже если некоторые узлы выходят из строя. Кроме того, P2P архитектура также может улучшить масштабируемость по мере увеличения количества узлов в сети. 759 | 760 | Полезные ссылки: 761 | 762 | * [Peer to Peer Architecture](https://student.cs.uwaterloo.ca/~cs446/1171/Arch_Design_Activity/Peer2Peer.pdf) 763 | 764 | ### по внутренней структуре 765 | 766 | Под структурой в архитектуре программного обеспечения следует понимать организацию и композицию компонентов программной системы, а также то, как они взаимодействуют друг с другом. Она имеет дело с физической организацией системы и взаимосвязями между различными компонентами. 767 | 768 | Существует несколько различных структурных шаблонов и стилей в архитектуре, которые можно использовать для разработки программных систем, в том числе: 769 | 770 | * Монолитная: когда система построена как единый, интегрированный и автономный элемент. 771 | * Многоуровневая: система разделена на ряд уровней, каждый из которых имеет определенную ответственность и взаимодействует с другими уровнями через четко определенные интерфейсы. 772 | * Микросервисы: когда система построена как набор небольших, независимых и слабо связанных сервисов. 773 | * Событийно-ориентированная: когда система реагирует на определенные происходящие события, а не постоянно опрашивается на наличие изменений. 774 | * Клиент-сервер: клиент отправляет запросы на сервер, а сервер отвечает на эти запросы. 775 | * Пиринговая: каждый узел в сети ведёт себя как клиент и сервер. 776 | * Компонентно-ориентированная: когда система состоит из повторно используемых и независимых программных компонентов. 777 | * Предметно-ориентированная: система организована вокруг смыслового ядра и сущностей бизнеса. 778 | 779 | #### компонентно-ориентированная 780 | 781 | В архитектуре программного обеспечения компонентно-ориентированное проектирование (CBD) — это подход к проектированию программных систем путем их составления из набора повторно используемых и независимых программных компонентов. Эти компоненты содержат определенные функциональные возможности и могут быть легко интегрированы в различные части системы, обеспечивая ей более модульную и гибкую конструкцию. 782 | 783 | В CBD программная система делится на набор компонентов, каждый из которых имеет четко определенный интерфейс и определенную ответственность. Эти компоненты можно разрабатывать, тестировать и развертывать независимо друг от друга, что упрощает добавление новых функций, изменение существующих и обслуживание системы. 784 | 785 | Полезные ссылки: 786 | 787 | * [Component Based Software architecture](https://www.tutorialspoint.com/software_architecture_design/component_based_architecture.htm) 788 | 789 | #### монолитная 790 | 791 | В архитектуре программного обеспечения монолитная архитектура — это подход к проектированию, при котором программная система строится как единая, интегрированная и автономная единица. В монолитной архитектуре все компоненты системы сильно связаны и зависят друг от друга. Это означает, что изменения в одной части системы могут повлиять на другие. 792 | 793 | Монолитная архитектура часто используется для систем малого и среднего размера, где сложность системы управляема, а потребность в масштабируемости и гибкости не так высока. В монолитной архитектуре вся система обычно создаётся, развертывается и выполняется как единое целое, что упрощает понимание системы и управление ею. 794 | 795 | Полезные ссылки: 796 | 797 | * [Overview of Monolithic Architecture](https://www.atlassian.com/microservices/microservices-architecture/microservices-vs-monolith) 798 | * [What is Monolithic architecture?](https://www.techtarget.com/whatis/definition/monolithic-architecture) 799 | * [What is Software Architecture? (Monolithic vs. Layered vs. Microservice)s](https://www.youtube.com/watch?v=_07NtoK-Kns) 800 | 801 | #### многоуровневая 802 | 803 | В архитектуре программного обеспечения многоуровневая архитектура — это подход к проектированию, при котором программная система делится на ряд уровней, каждый из которых имеет определенную ответственность и взаимодействует с другими уровнями через четко определенные интерфейсы. Этот подход обеспечивает более модульную и гибкую структуру, в которой каждый уровень может разрабатываться, тестироваться и развертываться независимо, что упрощает добавление новых функций, изменение существующих и обслуживание системы. 804 | 805 | Многоуровневая архитектура часто используется для больших и сложных систем, где необходима масштабируемость и гибкость. Каждый уровень в многоуровневой архитектуре отвечает за определенную функциональность и может рассматриваться как «черный ящик» с четко определенным интерфейсом. Уровни взаимодействуют друг с другом через эти интерфейсы, что позволяет четко разделить ответственность. 806 | 807 | Полезные ссылки: 808 | 809 | * [Layered Architectures](https://www.youtube.com/watch?v=0kpTKLTx8f4) 810 | * [Get started with Layered Architecture](https://cs.uwaterloo.ca/~m2nagapp/courses/CS446/1195/Arch_Design_Activity/Layered.pdf) 811 | 812 | ## Архитектурные шаблоны 813 | 814 | Архитектурные шаблоны — это набор решений, хорошо зарекомендовавших себя для определенных типов программных систем. Они формируют словарь часто используемых терминов и набор передовых методов проектирования и создания программных систем, а также могут помочь разработчикам принимать более обоснованные проектные решения. К наиболее часто применяемым архитектурным шаблонам относят: 815 | 816 | * Модель-представление-контроллер (Model-View-Controller, MVC): шаблон для разделения пользовательского интерфейса, бизнес-логики и компонентов для хранения данных системы. 817 | * Микросервисы: шаблон построения систем как набора небольших, независимо развертываемых сервисов, которые обмениваются данными по сети. 818 | * Событийно-ориентированный: шаблон для построения систем, которые реагируют на события и выполняют действия в ответ. 819 | * Многоуровневый: шаблон для организации системы по уровням, где каждый уровень предоставляет определенный набор сервисов вышестоящему уровню. 820 | * Каналы и фильтры (Pipe-and-Filter): шаблон построения систем в виде последовательности независимых повторно используемых обрабатывающих элементов, соединенных вместе в конвейер. 821 | * Разделение ответственности на команды и запросы (Command-Query Responsibility Segregation (CQRS)): шаблон, отделяющий обработку команд (которые изменяют состояние системы), от обработки запросов (которые извлекают информацию из системы). 822 | * «Доска объявлений»: шаблон для создания централизованного хранилища информации, к которому могут обращаться и изменять несколько независимых модулей или подсистем. 823 | * Микроядро: шаблон, целью которого является минимизация объема кода, выполняемого в режиме ядра, и перенос максимально возможного количества функций в процессы пользовательского режима. 824 | * Бессерверный: шаблон проектирования, который позволяет разработчикам создавать и запускать приложения и службы без необходимости выделения серверов и управления ими. 825 | * Очереди и потоки сообщений: шаблон, который разделяет различные компоненты системы и обеспечивает асинхронную связь между ними. 826 | * Генерация событий (Источники событий, Event Sourcing): шаблон, в котором сохраняются все изменения состояния системы в виде последовательности событий, а не только текущего состояния. 827 | 828 | Полезные ссылки: 829 | 830 | * [Overview - Architectural Pattern](https://en.wikipedia.org/wiki/Architectural_pattern) 831 | * [Architecture Patterns Used In Enterprise Software Development](https://www.youtube.com/watch?v=BrT3AO8bVQY) 832 | 833 | ### SOA 834 | 835 | SOA (сервис-ориентированная архитектура) — это архитектурный шаблон, который используется для проектирования и организации программных систем как набора сервисов, к которым можно получить доступ по сети. Эти сервисы представляют собой автономные, самостоятельные, функциональные единицы, которые можно повторно использовать и комбинировать для создания новых функциональных возможностей. SOA сервисы спроектированы так, чтобы быть слабо связанными, т. е. они не зависят от деталей реализации других сервисов, они взаимодействуют друг с другом через четко определенные интерфейсы, обычно с использованием протокола, такого как HTTP или SOAP. SOA обеспечивает ряд преимуществ по сравнению с другими архитектурными шаблонами, например возможность повторного использования, модульность, совместимость и масштабируемость. Его можно реализовать с помощью различных технологий, таких как веб-сервисы, REST и микросервисы. 836 | 837 | Полезные ссылки: 838 | 839 | * [Overview of Service-Oriented Architecture](https://medium.com/design-microservices-architecture-with-patterns/service-oriented-architecture-1e4716fbca17) 840 | * [Tutorial - Service-Oriented Architecture -SOA](https://www.youtube.com/watch?v=jNiEMmoTDoE) 841 | * [What is Service-Oriented Architecture 842 | ](https://www.youtube.com/watch?v=_dFJOSR-aFs) 843 | 844 | ### CQRS 845 | 846 | CQRS (Разделение ответственности на команды и запросы, Command Query Responsibility Segregation) — это архитектурный шаблон, который используется для разделения обязанностей чтения и записи данных в программной системе. В CQRS архитектуре система разделена на две отдельные части: команды и запросы. 847 | 848 | Команды отвечают за обработку команд и обновление состояния системы, а запросы — за считывание текущего состояния системы и возврат результатов клиенту. Команды и запросы могут использовать разные модели данных, механизмы хранения и даже разные технологии. 849 | 850 | Полезные ссылки: 851 | 852 | * [Get Started with CQRS Pattern](https://learn.microsoft.com/en-us/azure/architecture/patterns/cqrs) 853 | * [CQRS Software Architecture Pattern: The Good, Bad, and the Ugly](https://betterprogramming.pub/cqrs-software-architecture-pattern-the-good-the-bad-and-the-ugly-e9d6e7a34daf) 854 | 855 | ### Предметно-ориентированное проектирование 856 | 857 | Предметно-ориентированное проектирование (DDD) — это архитектурный шаблон, который используется для проектирования программных систем, на основе смыслового ядра и сущностях бизнеса. Он ориентирован на создание четкого и точного представления предметной области в программной системе, а также на согласование программной системы с целями и задачами бизнеса. DDD имеет ряд преимуществ по сравнению с другими архитектурными шаблонами, например, соответствие целям и задачам бизнеса, более эффективное взаимодействие между экспертами в предметной области и разработчиками, четкую и выразительную модель предметной области, а также улучшенную масштабируемость и удобство сопровождения. Он реализуется с использованием набора принципов и шаблонов, таких как стратегическое проектирование, подобласти, ограниченный контекст, сущности, объекты-значения, агрегат и репозиторий. 858 | 859 | Полезные ссылки: 860 | 861 | * [What is DDD (Domain-Driven Design)?](https://www.youtube.com/watch?v=Tnecs_7OT74) 862 | * [Domain-Driven Design patterns for a distributed system](https://www.youtube.com/watch?v=i3d_jzpf0gE) 863 | * [Modern Software Architecture (#1): Domain Driven Design](https://medium.com/modern-software-architecture/modern-software-architecture-1-domain-driven-design-f06fad8695f9) 864 | * [The Concept of Domain-Driven Design Explained](https://medium.com/microtica/the-concept-of-domain-driven-design-explained-3184c0fd7c3f) 865 | 866 | ### Модель-представление-контроллер (Model-View-Controller) 867 | 868 | Модель-представление-контроллер (MVC) — это архитектурный шаблон, который разделяет задачи программной системы на три отдельных компонента: модель, представление и контроллер, где модель олицетворяет данные и бизнес-логику системы, представление — пользовательский интерфейс системы, а контроллер действует как посредник между моделью и представлением. Основная цель MVC — разделить отвесттвенность в системе, упрощая ее понимание, поддержку и развитие. Он широко используется в веб-разработке. 869 | 870 | Полезные ссылки: 871 | 872 | * [MVC Design Pattern](https://www.geeksforgeeks.org/mvc-design-pattern/) 873 | * [MVC Framework - Introduction](https://www.tutorialspoint.com/mvc_framework/mvc_framework_introduction.htm) 874 | * [Tutorial - MVC Architectural Pattern](https://www.youtube.com/watch?v=e9S90R-Y24Q) 875 | 876 | ### Микросервисы 877 | 878 | Микросервисы — это архитектурный шаблон, который используется для проектирования программных систем как набора небольших, независимых и слабо связанных сервисов. Каждый сервис отвечает за определенный функционал и может разрабатываться, развертываться и масштабироваться независимо. Основное преимущество архитектуры микросервисов заключается в том, что она позволяет сделать систему более гибкой и масштабируемой, а также улучшает локализацию ошибок и ускоряет развертывание. Он часто используется в сочетании с другими архитектурными шаблонами и стилями, такими как событийно-ориентированная архитектура, CQRS и сервис-ориентированная архитектура. 879 | 880 | Полезные ссылки: 881 | 882 | * [Tutorial - Microservices Architectural Pattern](https://www.youtube.com/watch?v=8BPDv038oMI) 883 | * [Get started with Microservices Design Patterns](https://www.youtube.com/watch?v=xuH81XGWeGQ) 884 | * [Brief of Microservices](https://microservices.io/patterns/microservices.html) 885 | * Ричардсон Крис, Микросервисы. Паттерны разработки и рефакторинга. — СПб.: Питер, 2019. — 544 с.: ил. — (Серия «Библиотека программиста»). 886 | 887 | ### Шаблон Blackboard («доска объявлений») 888 | 889 | Архитектурный шаблон «Доска объявлений» — это шаблон проектирования программного обеспечения, который позволяет создавать централизованное хранилище информации, к которому могут обращаться и изменять несколько независимых модулей или подсистем. «Доска» служит механизмом связи и координации между этими модулями, позволяя им обмениваться информацией и взаимодействовать для достижения общей цели. Этот шаблон часто используется в системах искусственного интеллекта и принятия решений, где несколько процессов или агентов должны совместно использовать сложные данные и анализировать их. 890 | 891 | Полезные ссылки: 892 | 893 | * [Overview of Blackboard (design pattern)](https://en.wikipedia.org/wiki/Blackboard_(design_pattern)) 894 | 895 | ### Микроядро 896 | 897 | Микроядро — это архитектурный шаблон, используемый при разработке операционной системы, целью которого является минимизировать объем кода, работающего в режиме ядра (т. е. привилегированный режим с прямым доступом к аппаратным ресурсам), и вместо этого перенести как можно больше функций в пользовательский режим. Это достигается за счет создания небольшого минималистического ядра, которое выполняет только основные задачи, такие как управление памятью, планирование процессов и межпроцессное взаимодействие (IPC), а весь остальной функционал реализуется в процессах пользовательского режима. 898 | 899 | Полезные ссылки: 900 | 901 | * [Microkernel Architectural Pattern | Software Architecture](https://www.youtube.com/watch?v=h3icQDMRLd8) 902 | * [Overview of Microkernel Architecture](https://www.oreilly.com/library/view/software-architecture-patterns/9781491971437/ch03.html) 903 | 904 | ### Бессерверная архитектура 905 | 906 | Бессерверная архитектура — это шаблон проектирования, который позволяет разработчикам создавать и запускать приложения и сервисы без необходимости выделения серверов и управления ими. Вместо этого эти приложения и сервисы выполняются в полностью управляемой среде, такой как AWS Lambda, Azure Functions или Google Cloud Functions, где инфраструктура и масштабирование выполняются автоматически поставщиком облачных услуг. 907 | 908 | Этот архитектурный шаблон в основном фокусируется на бизнес-логике и управлении событиями, а не на управлении сервером. Это позволяет разработчикам писать и развертывать код в небольших одноцелевых функциях, которые запускаются определенными событиями, такими как изменения в базе данных или поступление новых данных в поток. 909 | 910 | Полезные ссылки: 911 | 912 | * [Serverless Architecture Patterns in AWS](https://waswani.medium.com/serverless-architecture-patterns-in-aws-edeab0e46a32) 913 | 914 | ### Очереди сообщений / потоки 915 | 916 | Очереди сообщений и потоки — это архитектурные шаблоны, которые используются для разделения различных компонентов системы и обеспечения асинхронной связи между ними. 917 | 918 | Очереди сообщений: Очередь сообщений — это программный компонент, который позволяет нескольким системам или приложениям взаимодействовать друг с другом путем передачи сообщений между ними. Сообщения хранятся в очереди и каждое сообщение обрабатывается одним потребителем. Этот шаблон полезен для систем, в которых существует высокая степень изменчивости скорости создания и потребления сообщений, и где отправитель и получатель не должны быть активны в одно и то же время. Примерами систем очередей сообщений являются Apache Kafka, RabbitMQ и Amazon SQS. 919 | 920 | Полезные ссылки: 921 | 922 | * [System Design — Message Queues](https://medium.com/must-know-computer-science/system-design-message-queues-245612428a22) 923 | * [Overview of Message Queue pattern](https://badia-kharroubi.gitbooks.io/microservices-architecture/content/patterns/communication-patterns/message-queue-pattern.html) 924 | 925 | ### Генерация событий (Источники событий, Event Sourcing) 926 | 927 | Источники событий — это архитектурный шаблон, который используется для создания систем, которым необходимо вести историю всех изменений, которые произошли с течением времени. Этот шаблон сохраняет все изменения состояния системы в виде последовательности событий, а не только текущего состояния. 928 | 929 | В этом шаблоне все изменения состояния системы обрабатываются как события, и эти события сохраняются в логе только для добавления данных, также называемом хранилищем событий. Текущее состояние системы может быть восстановлено из лога событий в любой момент времени путем воспроизведения событий из него. 930 | 931 | Полезные ссылки: 932 | 933 | * [Event Sourcing Pattern](https://learn.microsoft.com/en-us/azure/architecture/patterns/event-sourcing) 934 | * [Design Patterns: Why Event Sourcing?](https://www.youtube.com/watch?v=rUDN40rdly8) 935 | 936 | ## Шаблоны корпоративных приложений 937 | 938 | Шаблоны корпоративных приложений — это набор шаблонов проектирования, которые обычно используются при разработке корпоративного программного обеспечения. Эти шаблоны содержат словарь часто употребляемых терминов и набор лучших практик для решения часто встречающихся проблем, возникающих при разработке больших и сложных программных систем. Ниже приведены некоторые примеры шаблонов корпоративных приложений: 939 | 940 | * Предметно-ориентированное проектирование (DDD) 941 | * Модель-представление-контроллер (MVC) 942 | * Сервис-ориентированная архитектура (SOA) 943 | * Принцип разделения ответственности на команды и запросы (CQRS) 944 | * Генерация событий (Источники событий, Event Sourcing) 945 | * Микросервисы 946 | * Событийно-ориентированная архитектура (EDA) 947 | 948 | Эти шаблоны могут помочь улучшить поддержку и масштабируемость программного обеспечения, обеспечивая четкое разделение задач и позволяя использовать более модульную и гибкую архитектуру. 949 | 950 | Полезные ссылки: 951 | 952 | * [Software Architecture Patterns in Enterprise Software](https://blog.devgenius.io/10-software-architecture-patterns-in-enterprise-software-development-fabacb5ed0c8) 953 | * [What are Enterprise Integration Patterns?](https://www.youtube.com/watch?v=WNm3QmJadNs) 954 | 955 | ### Объекты переноса данных (DTOs) 956 | 957 | Шаблон проектирования Объект переноса данных — это один из архитектурных шаблонов корпоративных приложений, который требует использовать объекты, объединяющие и инкапсулирующие данные для передачи. Объект переноса данных, по сути, подобен структуре данных. Он не должен содержать никакой бизнес-логики, но должен содержать механизмы сериализации и десериализации. 958 | 959 | Полезные ссылки: 960 | 961 | * [Data Transfer Object](https://martinfowler.com/eaaCatalog/dataTransferObject.html) 962 | * [Data Transfer Object pattern and Mappers](https://medium.com/@abdalrhmanalkraien/data-transfer-object-pattern-and-mapper-116508bc9df0) 963 | 964 | ### Коллекции объектов (Identity Maps) 965 | 966 | Коллекции объектов — это шаблон, используемый при разработке корпоративных приложений для поддержки карты объектов, которые были загружены из базы данных, где ключом является их уникальный идентификатор. Они используются для предотвращения создания в памяти нескольких копий одного и того же объекта при многократном доступе к одним и тем же данным. 967 | 968 | Шаблон Коллекция объектов обычно используется в сочетании с таким инструментом как ORM (объектно-реляционным отображением). Перед тем как объект извлекается из базы данных, сначала происходит сверка с коллекцией объектов, чтобы убедиться, что он уже не был загружен ранее. Если 969 | он уже находится в коллекции, то возвращается существующий объект, а не создается новая копия. 970 | 971 | Полезные ссылки: 972 | 973 | * [Identity Map](https://martinfowler.com/eaaCatalog/identityMap.html) 974 | * [Overview of Identity map pattern](https://en.wikipedia.org/wiki/Identity_map_pattern) 975 | * [Tutorial - Identity Map Design Pattern](https://youtube.com/watch?v=erDxkIyNudY) 976 | 977 | ### Особые случаи использования (Use Cases) 978 | 979 | Особые случаи использования — это шаблон, применяемый при разработке корпоративных приложений для представления функциональных требований системы. Они описывают взаимодействие между системой и её пользователями, а также шаги, необходимые для достижения конкретной цели. Особые случаи использования — это способ зафиксировать требования к системе таким образом, чтобы их было легко понять как команде разработчиков, так и заинтересованным сторонам. 980 | 981 | Особый случай использования — это описание последовательности действий, которые система выполняет в ответ на запрос пользователя для достижения определенной цели. Особый случай использования обычно включает в себя: 982 | 983 | * Áктор (пользователь), который инициирует действие 984 | * Цель, которую хочет достичь а́ктор 985 | * Шаги, необходимые для достижения цели, включая любые альтернативные пути или условия, приводящие к ошибке 986 | * Ожидаемый результат взаимодействия 987 | 988 | Особые случаи использования часто являются основопологающими при проектировании и разработке системы, поскольку они обеспечивают чёткое и более глубокое понимание требований к ней. 989 | 990 | Полезные ссылки: 991 | 992 | * [Use Case Patterns](https://caminao.blog/how-to-implement-symbolic-representations/patterns/functional-patterns/use-case-patterns/) 993 | 994 | ### Репозитории (Repositories) 995 | 996 | Репозитории — это шаблон, используемый при разработке корпоративных приложений для обеспечения согласованного и абстрактного способа доступа к хранилищу данных. Репозитории по сути являются уровнем абстракции между приложением и хранилищем данных, предоставляя согласованный и простой API для доступа к данным и манипулирования ими. 997 | 998 | Репозиторий — это шаблон, который можно использовать для организации кода доступа к данным и инкапсуляции логики извлечения и хранения объектов. Репозитории обеспечивают отделение проблемы доступа к данным от остальной части приложения, позволяя писать код приложения для интерфейса, а не для конкретной технологии хранения данных. 999 | 1000 | Полезные ссылки: 1001 | 1002 | * [Repository](https://martinfowler.com/eaaCatalog/repository.html) 1003 | * [Tutorial - Repository Design Pattern](https://www.youtube.com/watch?v=mb6bwnEaZ3U) 1004 | * [Introduction to Repository Design Patterns](https://cubettech.com/resources/blog/introduction-to-repository-design-pattern/) 1005 | 1006 | ### Преобразователи (Mappers) 1007 | 1008 | Преобразователи — это шаблон, используемый при разработке корпоративных приложений для обеспечения согласованного и абстрактного способа сопоставления между различными моделями данных. Они по сути представляют собой уровень абстракции между приложением и хранилищем данных, предоставляя согласованный и простой API для преобразования данных. 1009 | 1010 | Преобразователь — это компонент, который можно использовать для перевода данных из одного формата или модели в другой. Например, его можно использовать для преобразования данных из модели базы данных в модель предметной области или из модели предметной области в объект переноса данных (DTO). 1011 | 1012 | Полезные ссылки: 1013 | 1014 | * [Mapper](https://martinfowler.com/eaaCatalog/mapper.html) 1015 | * [Overview of Data Mapper Pattern](https://en.wikipedia.org/wiki/Data_mapper_pattern) 1016 | * [Tutorial - Mappers](https://www.youtube.com/watch?v=7noMLStHcTE) 1017 | 1018 | ### Сценарий транзакции (Transaction Script) 1019 | 1020 | Сценарий транзакции — это шаблон, используемый в разработке корпоративных приложений, который организует бизнес-логику в единый процедурный сценарий. Он часто используется для простых операций CRUD (создание, чтение, обновление, удаление), где вся логика для конкретной транзакции содержится в одном скрипте или функции. Этот шаблон прост в реализации и понятен, но может стать громоздким по мере увеличения сложности приложения. Альтернативные шаблоны, такие как предметно-ориентированное проектирование (DDD) и шаблон Active Record, могут лучше подходить для более сложных приложений. 1021 | 1022 | Полезные ссылки: 1023 | 1024 | * [Transaction Script](https://martinfowler.com/eaaCatalog/transactionScript.html) 1025 | * [Transaction Script Pattern](https://gunnarpeipman.com/transaction-script-pattern/) 1026 | * [Tutorial - Transaction Script Design Pattern](https://www.youtube.com/watch?v=fnsU9cqcY3I) 1027 | 1028 | ### Команды / Запросы (Commands / Queries) 1029 | 1030 | Шаблон разделения ответственности на команды и запросы (CQRS) — это методика, используемая при разработке корпоративных приложений для разделения обязанностей по обработке операций, связанных с записью (команд), от операций, связанных с чтением (запросов), для выполнении действий, которые изменяют состояние системы, таких как создание, обновление или удаление данных. Эти операции реализуются обработчиками команд, которые отвечают за проверку данных и выполнение соответствующей бизнес-логики. 1031 | 1032 | Запросы используются для извлечения данных из системы, например для чтения данных из базы данных или кэша. Эти операции осуществляются обработчиками запросов, которые отвечают за выполнение соответствующего запроса и возврат данных вызывающей стороне. 1033 | 1034 | Полезные ссылки: 1035 | 1036 | * [Get Started with CQRS Pattern](https://learn.microsoft.com/en-us/azure/architecture/patterns/cqrs) 1037 | 1038 | ### Объекты-значения (Value Objects) 1039 | 1040 | Объекты-значения — это шаблон, используемый в разработке корпоративных приложений для представления простых неизменяемых значений, используемых для моделирования понятий предметной области. Обычно они используются для инкапсуляции данных, которые не являются сущностью, но важны для предметной области. 1041 | 1042 | Объект-значение определяется своим значением, не имеет собственной идентичности, уникальности, что означает, что два объекта-значения с одинаковым значением считаются равными, независимо от их идентичности. 1043 | 1044 | Полезные ссылки: 1045 | 1046 | * [Value Object](https://martinfowler.com/eaaCatalog/valueObject.html) 1047 | * [Overview - Implement Value Objects](https://learn.microsoft.com/en-us/dotnet/architecture/microservices/microservice-ddd-cqrs-patterns/implement-value-objects) 1048 | * [Intro to Value object](https://en.wikipedia.org/wiki/Value_object) 1049 | 1050 | ### Модели предметной области (Domain Models) 1051 | 1052 | Модели предметной области — это шаблон, используемый при разработке корпоративных приложений для представления бизнес-концепций и правил конкретной предметной области. Обычно они используются для моделирования проблемной области или области знаний конкретного бизнеса. 1053 | 1054 | Модель предметной области — это набор объектов, которые представляют реальные понятия и сущности предметной области. Эти объекты обычно моделируются как классы или типы и инкапсулируют данные и поведение, специфичные для предметной области. Они несут ответственность за представление состояния и поведения бизнес-концепций, которые они моделируют, а также за соблюдение правил и ограничений предметной области. 1055 | 1056 | Полезные ссылки: 1057 | 1058 | * [Domain Model](https://martinfowler.com/eaaCatalog/domainModel.html) 1059 | * [Overview - Domain Models](https://sparxsystems.com/enterprise_architect_user_guide/14.0/model_domains/specialized_models.html) 1060 | * [Tutorial - Domain Model Pattern](https://www.youtube.com/watch?v=75EGANiqADw) 1061 | 1062 | ### Сущности (Entities) 1063 | 1064 | Сущности — это шаблон, используемый в разработке корпоративных приложений для представления бизнес-концепций с уникальным идентификатором и временем существования. Обычно они используются для моделирования реальных объектов или понятий, которые имеют четкую идентичность и жизненный цикл, например клиент, заказ или учётная запись. 1065 | 1066 | Сущность определяется своей идентичностью, что означает, что две сущности с одной и той же идентичностью считаются одним и тем же, независимо от их состояния. Сущности обычно имеют уникальный идентификатор, например первичный ключ, который используется для их идентификации. У них также есть связанный набор свойств или атрибутов, описывающих их состояние. 1067 | 1068 | Полезные ссылки: 1069 | 1070 | * [What is entity in a programming language?](https://www.quora.com/What-is-entity-in-a-programming-language) 1071 | 1072 | ### Объектно-реляционные отображения (ORMs) 1073 | 1074 | ORM расшифровывается как Object-Relational Mapping (Объектно-реляционное отображение), это методика, используемая при разработке корпоративных приложений для сопоставления между моделью объектно-ориентированного программирования и моделью реляционной базы данных. Это позволяет разработчикам работать с объектами в своем коде, в то время как инструмент ORM заботится о переводе этих объектов в соответствующие операции с базой данных. 1075 | 1076 | ORM предназначены для того, чтобы абстрагироваться от сложности работы с реляционной базой данных и позволить разработчикам взаимодействовать с базой данных с помощью объектно-ориентированного API более высокого уровня. Они предоставляют набор библиотек и инструментов, которые сопоставляют объекты в коде с таблицами и строками в базе данных и наоборот. Это позволяет разработчикам работать с данными, используя знакомую объектно-ориентированную парадигму, вместо того, чтобы писать сложные SQL-запросы. 1077 | 1078 | Полезные ссылки: 1079 | 1080 | * [Why do you need an ORM?](https://enterprisecraftsmanship.com/posts/do-you-need-an-orm/) 1081 | 1082 | --------------------------------------------------------------------------------------------------------------------------- 1083 | 1. Вервов Вон. Предметно-ориентированное проектирование: самое основное.: Пер. с англ. - СпВ.: ООО "Альфа-книга". 2017. - 160 с.: ил. - Парал. тит. англ. 1084 | 2. Вернов Вон. Реализация методов предметно-ориентированного проектирования.: Пер. с англ. - М.: ООО "И.Д. Вильямс", 2016. - 688 с.: ил. - Парал. тит. англ. 1085 | 3. Фаулер, Мартин. Шаблоны корпоративных приложений.: Пер. с англ. - М.: ООО "И. Д. Вильямс", 2016. - 544 с.: ил. - Парал. тит. англ. 1086 | 4. Эванс Эрик. Предметно-ориентированное проектирование (DDD): структуризация сложных программных систем.: Пер. с англ. М.: ООО "И. Д. Вильямс", 2011. - 448 с.: ил. - Парал. тит. англ. 1087 | --------------------------------------------------------------------------------------------------------------------------- 1088 | 1089 | **Замечание.** Список, приведённый в данной дорожней карте, не является исчерпывающим. Здесь приведены лишь некоторые из наиболее важных тем, касающиеся каждого раздела. 1090 | -------------------------------------------------------------------------------- /static-methods-and-properties.md: -------------------------------------------------------------------------------- 1 | # [Статические методы и свойства](http://php.net/manual/ru/language.oop5.static.php) 2 | 3 | Объявление свойств и методов класса статическими позволяет обращаться к ним без создания экземпляра класса. 4 | 5 | Пример статического метода и свойсва. 6 | ```php 7 | 18 | ``` 19 | 20 | Поскольку доступ к статическому элементу осуществляется через класс, а не экземпляр объекта, вам не нужна переменная, которая ссылается на объект. Вместо этого используется имя класса, после которого указывается два двоеточия "::". 21 | 22 | ```php 23 | 29 | ``` 30 | 31 | Статические элементы имеют ряд полезных особенностей: 32 | 33 | 1) они доступны из любой точки сценария. Это означает, что можно вызывать функции, не передавая экземпляр класса от одного объекта другому или сохраняя экземпляр объекта в глобальной переменной. 34 | 2) статическое свойство доступно каждому экземпляру объекта этого класса, поэтому можно определить значения, которые должны быть доступны всем объектам данного типа. 35 | 3) позволяют не создавать экземпляр объекта ради вызова статической функции. 36 | -------------------------------------------------------------------------------- /system-design.md: -------------------------------------------------------------------------------- 1 | # Проектирование систем 2 | 3 | [Оригинал](https://roadmap.sh/system-design) 4 | 5 | ## Ссылки / Ресурсы 6 | 7 | * [System Design Primer](https://github.com/donnemartin/system-design-primer), [на русском](https://github.com/voitau/system-design-primer/blob/master/README-ru.md) 8 | * [Designing Data Intensive App](https://www.amazon.com/Designing-Data-Intensive-Applications-Reliable-Maintainable/dp/1449373321), [на русском](https://habr.com/ru/companies/piter/articles/352742/) 9 | 10 | ## Введение 11 | 12 | ### Что такое системное проектирование? 13 | 14 | Системное проектирование — это процесс определения элементов системы, а также их взаимодействий и связей с целью удовлетворения набора заданных требований. 15 | 16 | Он включает в себя формулировку проблемы, разбиение её на более мелкие компоненты и проектирование каждого компонента для эффективной совместной работы, позволяющей достичь общей цели системы. Этот процесс обычно включает в себя анализ текущей системы (если таковая имеется) и определение любых недостатков, создание подробного плана новой системы и тестирование проекта, чтобы убедиться, что он соответствует требованиям. Это итеративный процесс, который может включать несколько этапов проектирования, тестирования и доработки. 17 | 18 | Что касается разработки программного обеспечения, системное проектирование — это этап процесса разработки программного обеспечения, который фокусируется на высокоуровневом проектировании программной системы, включая архитектуру и компоненты. 19 | 20 | Оно также является одной из важных составляющих процесса собеседования для инженеров-программистов. Большинство компаний проводят специальный этап собеседования по проектированию системы, на котором кандидатов просят разработать систему для конкретной поставленной задачи. Ожидается, что кандидаты представят подробный проект системы, включая архитектуру, компоненты и их взаимодействие. Предполагается также, что они обговорят компромиссы, связанные с их разработкой, и альтернативы, которые они рассматривали. 21 | 22 | ### Как правильно осуществлять проектирование системы? 23 | 24 | При проектировании системы можно придерживаться следующей последовательности шагов: 25 | 26 | * **Понять проблему**: соберите информацию о проблеме, которую вы пытаетесь решить, и требованиях к системе. Определите пользователей и их потребности, а также любые ограничения системы. 27 | * **Определить область применения системы**: Определите границы системы, включая то, что система будет делать, а что нет. 28 | * **Исследовать и проанализировать существующие системы**: Рассмотрите аналогичные системы, созданные в прошлом, и определите, что работало хорошо, а что нет. Используйте эту информацию для обоснования своих проектных решений. 29 | * **Создать эскиз проекта**: Наметьте в общих частах основные компоненты системы и то, как они будут взаимодействовать друг с другом. Сюда можно отнести приблизительную схему архитектуры системы или блок-схему, описывающую процесс работы системы. 30 | * **Постепенно дорабатьвать проект**: Работая над элементами проекта, постепенно совершенствуйте его, пока не получите полный и детально проработанный проект, отвечающий всем требованиям. 31 | * **Создать документацию для проекта**: создайте подробную документацию вашего проекта для дальнейшего использования и поддержки. 32 | * **Постоянно контролировать и совершенствовать систему**: Проектирование системы — это не одноразовый процесс, его необходимо постоянно контролировать и совершенствовать, чтобы оно соответствовало меняющимся требованиям. 33 | 34 | Обратите внимание, что это общий подход к проектированию системы. 35 | Ответы на специфические вопросы, которые могут задать на собеседовании, можно найти по следующим ссылкам: 36 | * [How to approach System Design?](https://github.com/donnemartin/system-design-primer#how-to-approach-a-system-design-interview-question) 37 | * [What are system design questions?](https://www.hiredintech.com/system-design) 38 | * [My System Design Template](https://leetcode.com/discuss/career/229177/My-System-Design-Template) 39 | * [Intro to Architecture and Systems Design Interviews](https://www.youtube.com/watch?v=ZgdS0EUmn70) 40 | 41 | ### Для кого предназначено это руководство? 42 | 43 | ### Производительность/Масштабируемость 44 | 45 | ### Задержка/Пропускная способность 46 | 47 | ### Доступность/Согласованность данных 48 | 49 | #### Теорема CAP 50 | 51 | ##### Доступность + Устойчивость к разделению 52 | 53 | ##### Согласованность данных + Устойчивость к разделению 54 | 55 | ### Варианты согласованности данных 56 | 57 | Под вариантами согласованности данных подразумевают способы хранения и управления данными в распределенной системе, а также как эти данные становятся доступными для пользователей и приложений. Существует три основных типа согласованности: 58 | 59 | * Строгая согласованность 60 | * Слабая согласованность 61 | * Согласованность в конечном счёте 62 | 63 | Каждый из них имеет свои преимущества и недостатки, и выбор используемого типа будет зависеть от конкретных требований приложения или системы. 64 | 65 | Полезные ссылки: 66 | 67 | * [Consistency Patterns in Distributed Systems](https://cs.fyi/guide/consistency-patterns-week-strong-eventual/) 68 | 69 | #### Слабая согласованность 70 | 71 | #### Согласованность в конечном счёте 72 | 73 | #### Строгая согласованность 74 | 75 | ### Способы обеспечения доступности 76 | 77 | #### Аварийное переключение 78 | 79 | #### Active-passive 80 | 81 | #### Active-active 82 | 83 | #### Создание реплик (дублирование) 84 | 85 | #### Ведущий-ведущий 86 | 87 | #### Ведущий-ведомый 88 | 89 | --------------------------------------------------------------------------------