115 lines
3.4 KiB
Markdown
115 lines
3.4 KiB
Markdown
|
|
---
|
|||
|
|
title: Создание фабрики
|
|||
|
|
description: Пример создания фабрики business-модуля в React-проекте
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# Создание фабрики
|
|||
|
|
|
|||
|
|
Раздел показывает, как оформить фабрику business-модуля в React-проекте: описать публичный API, зависимости и функцию, возвращающую runtime API.
|
|||
|
|
|
|||
|
|
## Структура business-модуля
|
|||
|
|
|
|||
|
|
Фабрика лежит в корне business-модуля. Типы публичного API и зависимостей размещаются в `types/`.
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
business/customer/
|
|||
|
|
├── customer.factory.ts
|
|||
|
|
├── hooks/
|
|||
|
|
├── types/
|
|||
|
|
│ ├── customer.type.ts
|
|||
|
|
│ ├── customer-api.type.ts
|
|||
|
|
│ └── customer-factory.type.ts
|
|||
|
|
├── ui/
|
|||
|
|
└── index.ts
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## Тип публичного API
|
|||
|
|
|
|||
|
|
Публичный API описывает runtime-возможности, которые модуль отдаёт потребителям: хуки, компоненты и сценарные методы.
|
|||
|
|
|
|||
|
|
```ts
|
|||
|
|
// business/customer/types/customer-api.type.ts
|
|||
|
|
import type { ReactNode } from 'react'
|
|||
|
|
import type { Customer } from './customer.type'
|
|||
|
|
|
|||
|
|
export type CustomerCardProps = {
|
|||
|
|
customer: Customer
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
export type CustomerApi = {
|
|||
|
|
useCustomer: () => Customer | null
|
|||
|
|
CustomerCard: (props: CustomerCardProps) => ReactNode
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
```ts
|
|||
|
|
// business/customer/types/customer-factory.type.ts
|
|||
|
|
import type { CustomerApi } from './customer-api.type'
|
|||
|
|
|
|||
|
|
export type CustomerFactory = () => CustomerApi
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## Фабрика без зависимостей
|
|||
|
|
|
|||
|
|
Если модулю не нужны другие домены в runtime, фабрика создаётся без аргументов.
|
|||
|
|
|
|||
|
|
```ts
|
|||
|
|
// business/customer/customer.factory.ts
|
|||
|
|
import { useCustomer } from './hooks/use-customer.hook'
|
|||
|
|
import { CustomerCard } from './ui/customer-card'
|
|||
|
|
import type { CustomerFactory } from './types/customer-factory.type'
|
|||
|
|
|
|||
|
|
export const customerFactory: CustomerFactory = () => {
|
|||
|
|
return {
|
|||
|
|
useCustomer,
|
|||
|
|
CustomerCard,
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
```ts
|
|||
|
|
// business/customer/index.ts
|
|||
|
|
export { customerFactory } from './customer.factory'
|
|||
|
|
|
|||
|
|
export type { Customer } from './types/customer.type'
|
|||
|
|
export type { CustomerApi } from './types/customer-api.type'
|
|||
|
|
export type { CustomerFactory } from './types/customer-factory.type'
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## Фабрика с зависимостями
|
|||
|
|
|
|||
|
|
Если модулю нужен другой домен в runtime, зависимость передаётся аргументом фабрики. Тип зависимости описывает только нужную часть API.
|
|||
|
|
|
|||
|
|
```ts
|
|||
|
|
// business/order/types/order-deps.type.ts
|
|||
|
|
import type { CustomerApi } from '@/business/customer'
|
|||
|
|
|
|||
|
|
export type OrderDeps = {
|
|||
|
|
customer: Pick<CustomerApi, 'useCustomer'>
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
```ts
|
|||
|
|
// business/order/types/order-factory.type.ts
|
|||
|
|
import type { OrderApi } from './order-api.type'
|
|||
|
|
import type { OrderDeps } from './order-deps.type'
|
|||
|
|
|
|||
|
|
export type OrderFactory = (deps: OrderDeps) => OrderApi
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
```ts
|
|||
|
|
// business/order/order.factory.ts
|
|||
|
|
import { createUseOrder } from './hooks/use-order.hook'
|
|||
|
|
import { OrderCard } from './ui/order-card'
|
|||
|
|
import type { OrderFactory } from './types/order-factory.type'
|
|||
|
|
|
|||
|
|
export const orderFactory: OrderFactory = (deps) => {
|
|||
|
|
const useOrder = createUseOrder(deps)
|
|||
|
|
|
|||
|
|
return {
|
|||
|
|
useOrder,
|
|||
|
|
OrderCard,
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|