Untitled
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