import {Meta} from '@storybook/addon-docs/blocks'

<Meta title='@dxtmisha/ru/functional/Classes/DesignAbstract - Базовый класс конструктора'/>

# Класс DesignAbstract

Абстрактный базовый класс, предназначенный для управления свойствами конструктора и изменениями состояния. Он предоставляет структурированный способ обработки входных свойств, отслеживания изменений и выполнения обратных вызовов при обновлении данных.

## Ключевые особенности

- **Управление свойствами** — структурированная обработка входных данных (`props`) и хранилища событий (`event`).
- **Отслеживание изменений** — интеграция с `DesignChanged` для эффективного мониторинга и обновления изменений свойств.
- **Управление жизненным циклом** — автоматическое выполнение `makeCallback` и `initEvent` при обновлении данных.

## Инициализация

`DesignAbstract` является абстрактным базовым классом и не может быть инициализирован напрямую. Он служит основой для создания классов дизайна, которые управляют состоянием на основе входных свойств (`props`).

### Ограничения дженериков (Generic Constraints)

Класс использует два типа дженериков для обеспечения строгой типизации:
- `T extends Record<string, any>` — Тип для входных свойств (`props`). Определяет структуру данных, передаваемых в конструктор и используемых для отслеживания изменений.
- `C extends Record<string, any>` — Тип для выходных данных или состояния (`event`). Определяет структуру объекта, который формируется в `initEvent` и передается в обратные вызовы.

**Параметры конструктора:**
- `props: T` — объект с исходными данными для инициализации.
- `callback?: (event: C) => void` — дополнительная функция обратного вызова, которая выполняется после каждого обновления данных.
- `changed?: string[]` — список имен свойств из `props`, за которыми нужно следить. Если не указано, отслеживаются все ключи `props`.

**Обязательный метод для реализации:**
- `protected abstract initEvent(): void` — метод, в котором описывается логика преобразования или фильтрации `props` в объект состояния `event`.

```typescript
import { DesignAbstract } from '@dxtmisha/functional'

// 1. Определение структур
interface MyProps { label: string; value: number }
interface MyState { display: string }

// 2. Реализация конкретного класса
class MyDesign extends DesignAbstract<MyProps, MyState> {
  protected initEvent(): void {
    this.event.display = `${this.props.label}: ${this.props.value}`
  }
}

// 3. Создание экземпляра
const design = new MyDesign(
  { label: 'Счётчик', value: 10 }, 
  (state) => console.log('Новое состояние:', state.display)
)
```

## Методы управления данными

### `make`

Инициирует процесс обновления обратного вызова. Вызывает `makeCallback` и возвращает экземпляр для цепочки вызовов.

**Параметры:**
- `compelled?: boolean` — если `true`, принудительно обновляет данные независимо от наличия изменений.

**Возвращает:** `this`

### `makeCallback`

Основная логика выполнения для обновления состояния. Проверяет наличие изменений или принудительное обновление, затем инициализирует событие и запускает обратные вызовы.

**Параметры:**
- `compelled: boolean` — принудительно обновляет данные. По умолчанию: `false`.

**Возвращает:** `void`

## Защищенные методы (для наследников)

### `is`

Проверяет наличие значения в свойствах `props` по имени.

**Параметры:**
- `name: keyof T` — имя свойства.

**Возвращает:** `boolean`

### `isChanged`

Проверяет, было ли изменено значение свойства. Используется для предотвращения лишних вычислений.

**Параметры:**
- `name: keyof C` — имя свойства в событии.
- `nameProp?: keyof T | (keyof T)[]` — имя или список имен свойств в `props`, от которых зависит данное значение. Если не указано, используется `name`.

**Возвращает:** `boolean`

### `makeCallbackItem`

Выполняет вызов функции обратного вызова, переданной в конструктор.

**Возвращает:** `void`

### `initEvent` (абстрактный)

Абстрактный метод, который должен быть реализован в подклассе. В нем происходит заполнение объекта `this.event` на основе `this.props`.

**Возвращает:** `void`
