Перейти до основного вмісту

Фабрики

інформація

Фабрики - функціональна група призначена для виконання єдиного завдання - вибір, запуск та надання екземпляра стратегії / адаптера в залежності від конфігураційного параметра. Кожна фабрика також, конфігураційно може бути підключена чи відключена. Фабрики запускаються / зупиняються в рамках запуску / зупинки сервісу комбінацій CombinationService.

Архітектура

Фабрика поділяються на два фабрики адаптерів та фабрики стратегій.

Фабрики адаптерів

Фабрики адаптерів виконують запуск адаптера конкретного фреймворку відповідного протоколу. Так, наприклад, http веб-сервер може бути представлений fastify, express, koa та іншими фреймворками. Наразі X-Fiber реалізовує наступні адаптери:

НазваАдаптерОпис
HttpAdapterFastifyHttpAdapterРеалізовує адаптер http веб-сервера на базі fastify фреймворку
WsAdapterWsWsAdapterРеалізовує адаптер ws веб-сервера на базі ws бібліотеки

Фабрики адаптерів мають єдиний інтерфейс з методами run та stand, які визначають специфіку запуску та зупинку адаптера відповідного протоколу.

Фабрики стратегій

Фабрики стратегій як і фабрики адаптерів здійснюють вибір конкретної стратегії на основі конфігураційного значення, а самі стратегії повинні реалізовувати методи run та stand. Окрім цього фабрики стратегій надають екземпляр стратегії, оскільки кожна стратегія є кінцевою реалізацією. Наразі X-Fiber реалізовує наступні стратегії:

НазваСтратегіяОпис
FileStorageBufferFileStorageStrategyРеалізовує стратегію зберігання файлів в буфері веб-сервера.
FileStorageRedisFileStorageStrategyРеалізовує стратегію зберігання файлів в буфері веб-сервера підтримуючи два режими роботи: повного завантаження та завантаження частинами з послідуючим відвантаженням за механікою стрімінгу.
інформація

Підхід "Фабрика-стратегія" дозволяє уникнути привʼязки до конкретного інструмента, впроваджуючи загальний інтерфейс, до якого повинен бути приведений відповідний інструмент.

factory-arch.svg

Застосування

Застосування фабрик відбувається за єдиним сценарієм - в фабриці описується конфігурація вибору, а в сервісі комбінацій вони викликаються

// ** http.factory.ts */
import { injectable, inject } from '~packages'
import { CoreSymbols } from '~symbols'
import { AbstractFactory } from './abtract.factory'

import type {
IAbstractFactory,
IDiscoveryService,
ILoggerService,
IAbstractHttpAdapter
} from '~types'

@injectable()
export class HttpFactory extends AbstractFactory implements IAbstractFactory {
constructor(
@inject(CoreSymbols.DiscoveryService)
private readonly _discoveryService: IDiscoveryService,
@inject(CoreSymbols.LoggerService)
private readonly _loggerService: ILoggerService,
@inject(CoreSymbols.FastifyAdapter)
private readonly _fastifyAdapter: IAbstractHttpAdapter,
@inject(CoreSymbols.ExpressAdapter)
private readonly _expressAdapter: IAbstractHttpAdapter
) {
super();
}

public async run<T>(): Promise<void> {
const enable = this._discoveryService.getBoolean('adapters.http.enable', false);
if (!enable) return

const kind = this._discoveryService.getString('adapters.http.kind', 'fastify');
try {
switch (kind) {
case 'fastify':
await this._fastifyAdapter.start();
break;
case 'express':
await this._expressAdapter.start()
default:
throw new Error(`Http adapter kind is not supported. Use "fastify" or "express" kind`);
}
} catch (e) {
this._loggerService.error(e)
throw e
}
}

public async stand(): Promise<void> {
const enable = this._discoveryService.getBoolean('adapters.http.enable', false);
if (!enable) return

const kind = this._discoveryService.getString('adapters.http.kind', 'fastify');
try {
switch (kind) {
case 'fastify':
await this._fastifyAdapter.stop();
break;
case 'express':
await this._expressAdapter.stop()
default:
throw new Error(`Http adapter kind is not supported. Use "fastify" or "express" kind`);
}
} catch (e) {
this._loggerService.error(e)
throw e
}
}
}

// ** combination.service.ts */
import { injectable, inject } from '~packages'
import { CoreSymbols } from '~symbols'
import { AbstractService } from './abstract.service';

import type {
IAbstractService,
IDiscoveryService,
ILoggerService,
IAbstractFactory
} from '~types'

@injectable()
export class CombinationService extends AbstractService implements IAbstractService {
protected readonly _SERVICE_NAME = GetawayService.name;

constructor(
@inject(CoreSymbols.DiscoveryService)
protected readonly _discoveryService: IDiscoveryService,
@inject(CoreSymbols.LoggerService)
protected readonly _loggerService: ILoggerService,
@inject(CoreSymbols.FrameworkFactory)
private readonly _httpFactory: IAbstractFactory,
// ... other factory inject
) {
super();
}

protected async init(): Promise<boolean> {
try {
await this._httpFactory.run();
return true;
} catch (e) {
this._loggerService.error(e)
return false
}
}

protected async destroy(): Promise<void> {
try {
await this._httpFactory.stay();
return true;
} catch (e) {
this._loggerService.error(e)
return false
}
}
}

де:

  • HttpFactory - клас http фабрики.
    • @inject(CoreSymbols.FastifyAdapter) ... - впровадження fastify кінцевого http адаптера.
    • run - метод запуску визначення кінцевого адаптера та його запуск.
    • stay - метод зупинки кінцевого адаптера.
  • CombinationService - клас сервісу комбінацій.
    • init - метод запуску сервісу.
    • destroy - метод зупинки сервісу.