Соглашения

Дата обновления перевода 2024-07-17

Соглашения

Документ Стандарты написания кода описывает стандарты написания кода для проектов Symfony и внутренних и сторонних пакетов. Этот документ описывает стандарты написания кода и соглашения, используемые в базовом фреймворке, чтобы сделать его более целостным и предсказуемым. Мы рекомендуем вам следовать им в вашем коде, но вы не обязаны это делать.

Имена методов

Когда объект имеет "основную" множественную связь с относящимися к ней "вещами" (объектами, параметрами, ...), то имена методов нормализуются:

  • get()
  • set()
  • has()
  • all()
  • replace()
  • remove()
  • clear()
  • isEmpty()
  • add()
  • register()
  • count()
  • keys()

Использование этих методов разрешено только когда ясно, что существует главная связь:

  • CookieJar имеет множество объектов Cookie;
  • сервис Container имеет множество сервисов и параметров (так как сервисы - главная связь, соглашение именования используется для этой связи);
  • консоль Input имеет множество опций. "Основной" связи нет, поэтому соглашение именования не применяется.

Для многих связей, где соглашение не применяется, должны быть использованы следующие методы (где XXX - это имя связанной вещи):

??????? ????? ?????? ?????
get() getXXX()
set() setXXX()
?? ???????? replaceXXX()
has() hasXXX()
all() getXXXs()
replace() setXXXs()
remove() removeXXX()
clear() clearXXX()
isEmpty() isEmptyXXX()
add() addXXX()
register() registerXXX()
count() countXXX()
keys() ?? ????????

Note

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

Создание записи CHANGELOG

При добавлении новой функции в младшую версию или устаревании существующего поведения, необходимо добавить запись в соответствующий CHANGELOG.

Новые возможности и устаревания должны быть описаны в файле с именем CHANGELOG.md, который должен находиться в корневом каталоге измененного компонента, моста или пакета.

Файл должен быть написан с использованием синтаксиса Markdown и следовать следующим соглашениям:

  • Основное название всегда ``CHANGELOG'';
  • Каждая запись должна быть добавлена в раздел младшей версии (например, 5.3) в виде списка элемент;
  • Разделы третьего уровня не допускаются;
  • Сообщения должны соответствовать соглашениям сообщений коммитов : должны быть короткими, строка заглавными буквами, не заканчиваться точкой, использовать императивный глагол в начале строки;
  • Новые записи должны добавляться в начало списка.

Вот полный пример:

1
2
3
4
5
6
7
CHANGELOG
=========

5.3
---

 * Добавить `MagicConfig`, который позволяет конфигурировать вещи

Note

Основные файлы CHANGELOG-* в корневом каталоге symfony/symfony' автоматически генерируются при подготовке релизов и никогда не должны изменяться вручную.

Устаревание кода

Время от времени, некоторые классы и/или методы в фреймворке устаревают; это случается, когда реализация функции не может быть изменена из-за проблем ОС, но мы всё равно хотим предложить "Лучшую" альтернативу. В этом случае, старая реализация может быть просто устаревшей.

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

Новый класс (интерфейс, или черта) не может быть представлен как устаревший или содержать устаревшие методы.

Новый метод не может быть представлен как устаревший.

Функция помечается, как устаревшая, путём добавления phpdoc @deprecated к связанным классам, методам, свойствам, ...:

1
2
3
/**
 * @deprecated начиная с Symfony 5.1.
 */

Сообщение об устарении должно обозначать версию, когда класс/метод усарел, версию, когда он будет удалён, и, если возможно, как была заменена функция.

/**
  • @deprecated начиная с Symfony 5.1, вместо этого используйте Replacement.

*/

Если замена находится в другом пространстве имен, чем устаревший класс, необходимо использовать его FQCN:

1
2
3
/**
 * @deprecated начиная с Symfony 5.1, вместо этого используйте A\B\Replacement.
 */

Устаревание также должно быть запущено, чтобы помочь людям с миграцией (требуется пакет ``symfony/deprecation-contracts`):

1
trigger_deprecation('symfony/package-name', '5.1', 'Класс "%s" устарел, вместо этого используйте "%s".', Deprecated::class, Replacement::class);

При устаревании целого класса, вызов trigger_deprecation() должен быть размещен после деклараций использования, как в этом примере из ServiceRouterLoader:

1
2
3
4
5
6
7
8
9
10
namespace Symfony\Component\Routing\Loader\DependencyInjection;

use Symfony\Component\Routing\Loader\ContainerLoader;

trigger_deprecation('symfony/routing', '4.4', 'Класс "%s" устарел, вместо этого используйте "%s".', ServiceRouterLoader::class, ContainerLoader::class);

/**
 * @deprecated начиная с Symfony 4.4, вместо этого используйте Symfony\Component\Routing\Loader\ContainerLoader.
 */
class ServiceRouterLoader extends ObjectRouteLoader

Устаревание должно быть добавлено в файл CHANGELOG.md затрагиваемого компонента:

1
2
3
4
4.4
---

* Объявить класс `Deprecated` устаревшим, вместо этого использовать `Replacement`

Он также должен быть добавлен в файл UPGRADE.md целевой младшей версии (UPGRADE-4.4.md в нашем примере):

1
2
3
4
DependencyInjection
-------------------

* Объявить класс `Deprecated` устаревшим, вместо этого использовать `Replacement`

Наконец, его последствия должны быть добавлены в файл UPGRADE.md следующей старшей версии (UPGRADE-5.0.md в нашем примере):

1
2
3
4
DependencyInjection
-------------------

 * Удалить класс `Deprecated`, вместо этого использовать `Replacement`

Все эти задачи являются обязательными и должны быть выполнены в одном запросе на добавление.

Удаление устаревшего кода

Удаление устаревшего кода может быть произведено только раз в два года, в следующей старшей версии затрагиваемого компонента (ветка 6.0, ветка 7.0 и т.д.).

При удалении устаревшего кода последствия устаревания должны быть добавлены в файл CHANGELOG.md затрагиваемого компонента:

1
2
3
4
5.0
---

 * Удалить класс `Deprecated`, вместо этого использовать `Replacement`

Эта задача является обязательной и должна быть выполнена в том же запросе на добавление.

Именование команд и опций

Команды и их опции должны быть названы и описаны с использованием английского повелительного наклонения (например, 'run' вместо 'runs', 'list' вместо 'lists').
Использование императивного наклонения является лаконичным и соответствует похожим интерфейсам командной строки (как, например, основные страницы Unix).