You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NestJS多搜索服务动态调用场景适用哪种设计模式实现

适用设计模式:策略模式(配合简单工厂)

你的场景完全匹配策略模式的适用条件:多个业务逻辑(不同搜索引擎的搜索实现)具备统一的行为接口(都有search方法),需要根据传入参数动态选择使用哪一个逻辑,同时现有代码的多分支if判断维护成本高,刚好可以用策略模式优化。

优化实现步骤

1. 定义统一的搜索策略接口

先为所有搜索服务定义统一的行为契约,保证所有搜索服务的方法签名、返回结构完全对齐:

import { Observable } from "rxjs";
import { News } from "./your-news-entity-path";

export interface SearchStrategy {
  search(termOfSearch: string): Observable<{
    engine: string;
    total_news: number;
    data: News[];
  }>;
}

所有已有的搜索服务(TheGuardianService、NYTimesService等)都实现这个接口:

@Injectable()
export class TheGuardianService implements SearchStrategy {
  // 原有逻辑不变,确保search方法符合接口定义即可
}

2. 实现策略工厂服务

封装策略选择的逻辑,把引擎标识和对应服务的映射关系统一管理,避免散落在控制器里:

@Injectable()
export class SearchStrategyFactory {
  private strategyMap: Map<string, SearchStrategy> = new Map();

  constructor(
    private readonly nytimesService: NYTimesService,
    private readonly theguardianService: TheGuardianService,
    private readonly newscatcherService: NewscatcherService,
    private readonly newsapiService: NewsapiService,
    private readonly newsdataService: NewsdataService,
    private readonly summarizeService: SummarizeService,
  ) {
    // 注册所有搜索策略
    this.strategyMap.set('nytimes', this.nytimesService);
    this.strategyMap.set('theguardian', this.theguardianService);
    this.strategyMap.set('catcher', this.newscatcherService);
    this.strategyMap.set('newsapi', this.newsapiService);
    this.strategyMap.set('newsdata', this.newsdataService);
    this.strategyMap.set('any', this.summarizeService);
  }

  getStrategy(engine: string): SearchStrategy | undefined {
    return this.strategyMap.get(engine);
  }
}

如果后续要新增搜索引擎,只需要新增对应服务实现SearchStrategy接口,再在工厂的构造函数里加一行注册即可,不需要修改控制器逻辑。

3. 重构控制器代码

删掉所有if分支判断,直接通过工厂获取对应策略执行即可:

// 控制器内先注入策略工厂
constructor(private readonly searchStrategyFactory: SearchStrategyFactory) {}

// 原搜索接口处理逻辑
async handleSearch(@Query() query, @Req() req) {
  // 先处理any引擎的权限校验逻辑
  if (query.engine === 'any' && !req.user?.id) {
    return 'To search on all engines should be authenticated';
  }
  const strategy = this.searchStrategyFactory.getStrategy(query.engine);
  if (!strategy) {
    return 'Unknown engine';
  }
  return strategy.search(query.q);
}

优化收益

  • 符合开闭原则:新增/删除搜索引擎时不需要修改控制器核心逻辑,只需要调整策略工厂的注册逻辑
  • 代码可维护性大幅提升:消除了大量冗余的if分支判断,逻辑更清晰
  • 测试成本降低:每个搜索策略、策略工厂都可以独立做单元测试,不需要和控制器逻辑耦合

内容的提问来源于stack exchange,提问作者skyfall947

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 05:36:10