Угоди

Дата оновлення перекладу 2024-05-09

Угоди

Документ описує стандарти кодування для проектів Symfony
проектів, а також внутрішніх та сторонніх пакетів.Цей документ описує стандарти кодування та угоди, що використовуються в ядрі фреймворку, щоб зробити його більш узгодженим та передбачуваним. Ми заохочуємо вас слідувати їм у вашому власному коді, але ви не зобов'язані цього робити.

Іменування методу

Коли об'єкт має "головне" множинне відношення з пов'язаними з ним "речами"
(об'єктами, параметрами, ...), імена методів нормалізуються:

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

Використання цих методів дозволено лише тоді, коли зрозуміло, що існує
головний зв'язок:

  • a CookieJar має багато обʼєктів Cookie;
  • сервіс Container має багато сервісів та багато параметрів (оскільки сервіси
    є основним відношенням, для нього використовується угода про іменування);
  • Input консолі має багато аргументів та багато опцій. Не існує "головного" відношення, і тому угода про іменування не застосовується.

Для багатьох зв'язків, де ця конвенція не застосовується, натомість слід використовувати такі методи (де XXX - назва пов'язаного об'єкта):

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

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 автоматично генеруються під час підготовки релізів і ніколи не повинні змінюватися вручну.

Код застарівання

Час від часу деякі класи та/або методи у фреймворку застарівають; це трапляється, коли реалізація функції не може бути змінена через проблеми зворотної сумісності, але ми все одно хочемо запропонувати "кращу" альтернативу. У такому випадку стару реалізацію можна застаріти.

Застарівання може бути введено лише у наступній молодшій версії компонента (або пакета, мосту або контракту), на який це вплинуло. У виняткових випадках їх можна додати до попередніх підтримуваних версій, якщо вони є критично важливими.

Новий клас (або інтерфейс, або риса) не може бути представлений як застарілий, або містити застарілі методи.

Новий метод не може бути представлено як застарілий.

Властивість позначається як застаріла шляхом додавання PHPDoc @deprecated до відповідних класів, методів, властивостей, ...:

1
2
3
/**
 * @deprecated since Symfony 5.1.
 */

У повідомленні про застарівання має бути вказано версію, у якій функція застаріла, і, якщо можливо, як її було замінено:

1
2
3
/**
 * @deprecated since Symfony 5.1, use Replacement instead.
 */

Якщо заміна знаходиться в іншому просторі імен, ніж застарілий клас, слід використовувати його FQCN:

1
2
3
/**
 * @deprecated since Symfony 5.1, use A\B\Replacement instead.
 */

Щоб допомогти людям з міграцією, також має бути ініційовано застарівання (потребує пакет 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 since Symfony 4.4, use Symfony\Component\Routing\Loader\ContainerLoader instead.
 */
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).