Правила размера (Size)¶
Правила размера выявляют классы и пространства имен, которые стали слишком большими. Большие классы сложнее понять, протестировать и поддерживать. Эти правила устанавливают верхние границы допустимого размера.
Количество методов (Method Count)¶
Идентификатор правила: size.method-count
Что измеряет¶
Подсчитывает количество методов в классе. Класс со слишком большим количеством методов, вероятно, делает слишком много и должен быть разделен на более мелкие, сфокусированные классы.
Как читать значение:
| Методов | Интерпретация |
|---|---|
| 1--10 | Сфокусированный класс |
| 11--20 | Большой класс |
| 21--30 | Очень большой -- проверьте ответственности |
| 30+ | God Class -- немедленно разделите |
Пороговые значения¶
| Значение | Серьезность | Значение |
|---|---|---|
| 1--19 | OK | Приемлемый размер класса |
| 20--29 | Warning | Класс становится большим, подумайте о разделении |
| 30+ | Error | Класс слишком большой, нужен рефакторинг |
Конфигурация¶
| Опция | По умолчанию | Описание |
|---|---|---|
enabled |
true |
Включить или выключить правило |
warning |
20 |
Количество методов для предупреждения |
error |
30 |
Количество методов для ошибки |
Сокращённая запись с threshold:
bin/qmx check src/ --rule-opt="size.method-count:warning=25"
bin/qmx check src/ --rule-opt="size.method-count:error=40"
Пример¶
class OrderService
{
public function createOrder() { /* ... */ }
public function updateOrder() { /* ... */ }
public function deleteOrder() { /* ... */ }
public function findOrder() { /* ... */ }
public function listOrders() { /* ... */ }
public function validateOrder() { /* ... */ }
public function calculateTotal() { /* ... */ }
public function applyDiscount() { /* ... */ }
public function sendConfirmation() { /* ... */ }
public function generateInvoice() { /* ... */ }
public function processPayment() { /* ... */ }
public function refundOrder() { /* ... */ }
public function shipOrder() { /* ... */ }
public function trackShipment() { /* ... */ }
public function notifyCustomer() { /* ... */ }
public function exportToCSV() { /* ... */ }
public function importFromCSV() { /* ... */ }
public function archiveOrder() { /* ... */ }
public function restoreOrder() { /* ... */ }
public function auditOrder() { /* ... */ }
// ...и еще -- этот класс делает всё!
}
Как исправить¶
-
Определите группы методов. Найдите кластеры методов, которые работают вместе (например, все методы оплаты, все методы уведомлений).
-
Извлеките сервисные классы. Переместите каждую группу в свой класс:
-
Используйте композицию. Если исходный класс должен оркестрировать эти операции, внедрите новые сервисы как зависимости.
Количество классов (Class Count)¶
Идентификатор правила: size.class-count
Что измеряет¶
Подсчитывает количество классов в пространстве имен (пакете). Измеряется на уровне пространства имен, а не класса. Пространство имен со слишком большим количеством классов трудно обозревать, и его область ответственности, скорее всего, слишком широка.
Как читать значение:
| Классов | Интерпретация |
|---|---|
| 1--10 | Сфокусированное пространство имён |
| 11--15 | Умеренное |
| 16--25 | Большое -- рассмотрите разделение на подпространства |
| 25+ | Раздутое пространство имён |
Пороговые значения¶
| Значение | Серьезность | Значение |
|---|---|---|
| 1--14 | OK | Сфокусированное пространство имен |
| 15--24 | Warning | Пространство имен переполнено |
| 25+ | Error | Нужно разделить на подпространства имен |
Конфигурация¶
| Опция | По умолчанию | Описание |
|---|---|---|
enabled |
true |
Включить или выключить правило |
warning |
15 |
Количество классов для предупреждения |
error |
25 |
Количество классов для ошибки |
Сокращённая запись с threshold:
bin/qmx check src/ --rule-opt="size.class-count:warning=20"
bin/qmx check src/ --rule-opt="size.class-count:error=30"
Пример¶
App\Service\ # 28 классов -- слишком много!
├── UserService.php
├── OrderService.php
├── PaymentService.php
├── NotificationService.php
├── ReportService.php
├── ... (еще 23 файла)
Как исправить¶
-
Сгруппируйте связанные классы в подпространства имен:
-
Следуйте принципу единственной ответственности на уровне пространства имен -- каждое пространство имен должно представлять одну связную концепцию.
Количество свойств (Property Count)¶
Идентификатор правила: size.property-count
Что измеряет¶
Подсчитывает количество свойств (полей) в классе. Класс с большим количеством свойств часто имеет слишком много ответственностей или хранит слишком много состояния.
Как читать значение:
| Свойств | Интерпретация |
|---|---|
| 1--10 | Нормально |
| 11--15 | Много -- проверьте на группировку данных |
| 16--20 | Тяжёлый -- рассмотрите VO или разделение |
| 20+ | Чрезмерно |
Примечание
Это правило использует строгое сравнение (> вместо >=). Класс с ровно 15 свойствами не вызовет предупреждение; нужно 16 или более.
Пороговые значения¶
| Значение | Серьезность | Значение |
|---|---|---|
| 1--15 | OK | Приемлемое количество свойств |
| 16--20 | Warning | Слишком много свойств, подумайте об извлечении объектов |
| 21+ | Error | Значительно слишком много, нужен рефакторинг |
Конфигурация¶
| Опция | По умолчанию | Описание |
|---|---|---|
enabled |
true |
Включить или выключить правило |
warning |
15 |
Количество свойств, выше которого выдается предупреждение |
error |
20 |
Количество свойств, выше которого выдается ошибка |
excludeReadonly |
true |
Пропускать readonly классы (DTO, value objects) |
excludePromotedOnly |
true |
Пропускать классы, где все свойства -- promoted-параметры конструктора |
# qmx.yaml
rules:
size.property-count:
warning: 15
error: 20
exclude_readonly: true
exclude_promoted_only: true
Сокращённая запись с threshold:
bin/qmx check src/ --rule-opt="size.property-count:warning=18"
bin/qmx check src/ --rule-opt="size.property-count:error=25"
Пример¶
class ReportGenerator
{
private string $title;
private string $subtitle;
private string $author;
private \DateTimeInterface $createdAt;
private string $format;
private string $orientation;
private float $marginTop;
private float $marginBottom;
private float $marginLeft;
private float $marginRight;
private string $headerText;
private string $footerText;
private string $fontFamily;
private int $fontSize;
private string $colorScheme;
private bool $includeCharts;
private bool $includeTables;
private string $outputPath;
// 18 свойств -- этот класс знает слишком много!
}
Как исправить¶
-
Извлеките value objects. Сгруппируйте связанные свойства в небольшие, сфокусированные объекты:
class PageMargins { public function __construct( public readonly float $top, public readonly float $bottom, public readonly float $left, public readonly float $right, ) {} } class ReportStyle { public function __construct( public readonly string $fontFamily, public readonly int $fontSize, public readonly string $colorScheme, ) {} } class ReportGenerator { public function __construct( private ReportMetadata $metadata, private PageMargins $margins, private ReportStyle $style, private ReportOptions $options, ) {} } -
Ищите кластеры свойств -- свойства, которые всегда используются вместе, являются кандидатами на извлечение.
Совет
Классы, где все свойства -- promoted-параметры конструктора (типично для DTO), по умолчанию исключены через excludePromotedOnly. Это позволяет избежать ложных срабатываний на классах вроде CreateUserRequest(string $name, string $email, ...).