# 06. Условия и управляющие конструкции

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

---

## Длинные условия — выносите в методы

**ПЛОХО — НЕЧИТАЕМОЕ УСЛОВИЕ В IF**
```php
if ($deal->getStageId() === 'EXECUTING' && $deal->getOpportunity() > 10000 && $deal->getAssignedById() === $currentUserId && !$deal->getClosed()) {
    // разрешить действие
}
```

**ХОРОШО — ИНКАПСУЛИРОВАННОЕ УСЛОВИЕ**
```php
private function canCurrentUserEditDeal(\Bitrix\Crm\Item $deal): bool {
    return $deal->getStageId() === 'EXECUTING'
        && $deal->getOpportunity() > 10000
        && $deal->getAssignedById() === \CCrmSecurityHelper::GetCurrentUserID()
        && !$deal->getClosed();
}

if ($this->canCurrentUserEditDeal($deal)) {
    // разрешить действие
}
```

---

## Именованные константы и Enum вместо магических значений

**ПЛОХО — МАГИЧЕСКИЕ ЧИСЛА И СТРОКИ**
```php
if ($lead->getStatusId() === '1') { // что за статус?
    $action = 'call';
}
if ($product['QUANTITY'] < 10) { /* неясно откуда 10 */ }
```

**ХОРОШО — PHP 8.1+ ENUM**
```php
enum LeadStatus: string {
    case NEW = '1';
    case IN_PROCESS = '2';
    case CONVERTED = '3';
}

const LOW_STOCK_THRESHOLD = 10;

if ($lead->getStatusId() === LeadStatus::NEW->value) {
    $action = 'call';
}
if ($product['QUANTITY'] < LOW_STOCK_THRESHOLD) { /* ... */ }
```

---

## Полиморфизм вместо switch / if-elseif

**ПЛОХО — РАЗРАСТАЮЩИЙСЯ SWITCH**
```php
class ActivityHandler {
    public function process($activityType, $data) {
        if ($activityType === 'CALL') {
            // логика звонка
        } elseif ($activityType === 'EMAIL') {
            // логика письма
        } elseif ($activityType === 'MEETING') {
            // логика встречи — и так далее...
        } else {
            throw new \Exception('Unknown type');
        }
    }
}
```

**ХОРОШО — ПАТТЕРН STRATEGY + REGISTRY**
```php
interface ActivityProcessor {
    public function process(array $data): void;
}

class CallProcessor implements ActivityProcessor { /* ... */ }
class EmailProcessor implements ActivityProcessor { /* ... */ }

class ActivityProcessorRegistry {
    private array $processors = [];
    
    public function register(string $type, ActivityProcessor $p): void {
        $this->processors[$type] = $p;
    }
    
    public function get(string $type): ActivityProcessor {
        return $this->processors[$type]
            ?? throw new \InvalidArgumentException("Unknown activity type: {$type}");
    }
}
```

---

## match вместо if-elseif (PHP 8+)

**ПЛОХО**
```php
if ($stage === 'NEW') {
    $label = 'Новый';
} elseif ($stage === 'IN_PROGRESS') {
    $label = 'В работе';
} else {
    $label = 'Завершён';
}
```

**ХОРОШО — MATCH СО СТРОГИМ СРАВНЕНИЕМ**
```php
$label = match ($stage) {
    'NEW' => 'Новый',
    'IN_PROGRESS' => 'В работе',
    default => 'Завершён',
};
```