Untitled

mail@pastecode.io avatar
unknown
typescript
a month ago
5.3 kB
4
Indexable
Never
Да, вы правы в своих рассуждениях. ODataExpressionService действительно должен быть универсальным и работать как с массивами, так и с базой данных.

Вариант с добавлением условия в GetWithOData и реализацией двух версий для массивов и базы данных вполне жизнеспособен. Это позволит использовать единый интерфейс для обоих случаев, но потребует дополнительной работы по реализации двух версий для некоторых методов.

Основные изменения потребуются для методов tryFilter и всего operationService. Это может выглядеть примерно так:

GetWithOData(type: 'array' | 'database', ...) {
  if (type === 'array') {
    // Логика для работы с массивами
  } else {
    // Логика для работы с базой данных
  }
}

Такой подход позволит сохранить универсальность ODataExpressionService, но при этом учесть специфику работы с разными источниками данных.

Дополнительный слой абстракции под ODataExpressionService может не потребоваться, если вы реализуете эту логику внутри самого сервиса. Однако, если в будущем появится необходимость в поддержке дополнительных источников данных или более сложной логике выбора реализации, можно будет рассмотреть вариант с добавлением отдельного слоя абстракции.
я могу предложить вариант с дополнительным слоем абстракции для ODataExpressionService. Вот пример реализации:

// odata-data-source.ts
export interface ODataDataSource<T> {
    filter(filters: BaseODataFilter[]): Promise<T[]>;
    sort(sorts: ODataSort[]): Promise<T[]>;
    paginate(skip: number, top: number): Promise<T[]>;
    expand(expands: string[]): Promise<T[]>;
    select(selects: WithIndexer<string[]>): Promise<T[]>;
}

// array-data-source.ts
export class ArrayDataSource<T> implements ODataDataSource<T> {
    constructor(private data: T[]) {}

    async filter(filters: BaseODataFilter[]): Promise<T[]> {
        // Реализация фильтрации для массива
    }

    async sort(sorts: ODataSort[]): Promise<T[]> {
        // Реализация сортировки для массива
    }

    async paginate(skip: number, top: number): Promise<T[]> {
        // Реализация пагинации для массива
    }

    async expand(expands: string[]): Promise<T[]> {
        // Реализация расширения для массива
    }

    async select(selects: WithIndexer<string[]>): Promise<T[]> {
        // Реализация выборки для массива
    }
}

// database-data-source.ts
export class DatabaseDataSource<T> implements ODataDataSource<T> {
    constructor(private dbContext: any) {}

    async filter(filters: BaseODataFilter[]): Promise<T[]> {
        // Реализация фильтрации для базы данных
    }

    async sort(sorts: ODataSort[]): Promise<T[]> {
        // Реализация сортировки для базы данных
    }

    async paginate(skip: number, top: number): Promise<T[]> {
        // Реализация пагинации для базы данных
    }

    async expand(expands: string[]): Promise<T[]> {
        // Реализация расширения для базы данных
    }

    async select(selects: WithIndexer<string[]>): Promise<T[]> {
        // Реализация выборки для базы данных
    }
}

// odata-expression-service.ts
export class ODataExpressionService<T> {
    constructor(private dataSource: ODataDataSource<T>) {}

    async getWithOData(oDataConfig: ODataConfig): Promise<T[]> {
        let result = await this.dataSource.filter(oDataConfig.Filters);
        result = await this.dataSource.sort(oDataConfig.Sorts);
        result = await this.dataSource.paginate(oDataConfig.Skip!, oDataConfig.Top!);
        result = await this.dataSource.expand(oDataConfig.Expands);
        result = await this.dataSource.select(oDataConfig.Selects);
        return result;
    }
}

// usage-example.ts
const arrayData = [/* ... */];
const arrayDataSource = new ArrayDataSource(arrayData);
const arrayODataService = new ODataExpressionService(arrayDataSource);

const dbContext = /* ... */;
const dbDataSource = new DatabaseDataSource(dbContext);
const dbODataService = new ODataExpressionService(dbDataSource);

// Использование
const oDataConfig: ODataConfig = /* ... */;
const arrayResult = await arrayODataService.getWithOData(oDataConfig);
const dbResult = await dbODataService.getWithOData(oDataConfig);
Leave a Comment