# 02. Функции и методы

[← Оглавление](./index.md)

---

## Одна функция — одна ответственность (SRP)

**ПЛОХО**
```php
function processLeadAndSendNotification(array $data): void {
    // валидация, сохранение в CRM, отправка письма, логирование — всё в одном месте
}
```

**ХОРОШО**
```php
function validateLeadData(array $data): array { /* ... */ }
function createLead(array $validatedData): \Bitrix\Crm\Item { /* ... */ }
function sendLeadNotification(\Bitrix\Crm\Item $lead): void { /* ... */ }
```

---

## Избегайте флаговых аргументов (boolean trap)

**ПЛОХО**
```php
function addProductToDeal(int $dealId, array $productRow, bool $recalculate = true): void {
    // добавление товара
    if ($recalculate) {
        \CCrmDeal::Recalculate($dealId);
    }
}
```

**ХОРОШО — ДВА ЯВНЫХ МЕТОДА**
```php
function addProductToDeal(int $dealId, array $productRow): void {
    // только добавление товара
}

function addProductToDealAndRecalculate(int $dealId, array $productRow): void {
    $this->addProductToDeal($dealId, $productRow);
    \CCrmDeal::Recalculate($dealId);
}
```

---

## Количество параметров ≤ 3–4, иначе — DTO

**ПЛОХО**
```php
function updateCompany(int $id, string $title, string $phone, string $email, ?string $address, bool $isActive) { /* ... */ }
```

**ХОРОШО — READONLY DTO (PHP 8.2+)**
```php
readonly class UpdateCompanyDto {
    public function __construct(
        public string $title,
        public string $phone,
        public string $email,
        public ?string $address = null,
        public bool $isActive = true,
    ) {}
}

function updateCompany(int $id, UpdateCompanyDto $dto): void { /* ... */ }
```

---

## Ранний возврат (early return)

**ПЛОХО — ГЛУБОКАЯ ВЛОЖЕННОСТЬ**
```php
function getDiscountForDeal(\Bitrix\Crm\Item $deal): float {
    $discount = 0.0;
    if ($deal->getStageId() === 'EXECUTING') {
        $client = $deal->getClient();
        if ($client && $client->hasActiveSubscription()) {
            if ($deal->getOpportunity() > 100000) {
                $discount = 0.15;
            } else {
                $discount = 0.05;
            }
        }
    }
    return $discount;
}
```

**ХОРОШО — FLAT-СТРУКТУРА**
```php
function getDiscountForDeal(\Bitrix\Crm\Item $deal): float {
    if ($deal->getStageId() !== 'EXECUTING') {
        return 0.0;
    }
    $client = $deal->getClient();
    if (!$client || !$client->hasActiveSubscription()) {
        return 0.0;
    }
    return $deal->getOpportunity() > 100000 ? 0.15 : 0.05;
}
```