如何在TypeScript/JavaScript中合并两个日志类的方法?
整合两个日志类实现,遵循DRY原则的解决方案
问题场景
现有两个实现了LoggingTool接口的日志类:NativeLoggingTool和ServiceLoggingTool,两者方法签名完全一致。现在需要在部分环境中同时触发两个类的日志操作,但直接编写整合类会产生大量重复代码,希望找到更简洁的优化方案。
原类代码
NativeLoggingTool
export class NativeLoggingTool implements LoggingTool { private logger = new Logger(); public debug(message: string) { this.logger.debug(message); } public info(message: string) { this.logger.info(message); } }
ServiceLoggingTool
export class ServiceLoggingTool implements LoggingTool { public debug(message: string) { Service.setLevel('debug').captureMessage(message); } public info(message: string) { Service.setLevel('info').captureMessage(message); } }
原整合方案(存在重复代码)
export class NativeAndServiceLoggingTool implements LoggingTool { private logger = new Logger(); public debug(message: string) { this.logger.debug(message); Service.setLevel('debug').captureMessage(message); } public info(message: string) { this.logger.info(message); Service.setLevel('info').captureMessage(message); } }
解决方案:使用组合模式(Composite Pattern)
组合模式是这类场景的最佳选择,核心逻辑是创建一个组合类,注入多个LoggingTool实例,在每个方法中遍历调用所有实例的对应方法,彻底消除代码重复。
组合类实现
export class CompositeLoggingTool implements LoggingTool { // 注入需要整合的所有日志实例 constructor(private readonly loggers: LoggingTool[]) {} debug(message: string): void { this.loggers.forEach(logger => logger.debug(message)); } info(message: string): void { this.loggers.forEach(logger => logger.info(message)); } }
NestJS环境下的配置
结合NestJS的依赖注入体系,用工厂函数灵活控制不同环境的日志实现:
@Module({ providers: [ NativeLoggingTool, ServiceLoggingTool, { provide: LoggingTool, useFactory: (nativeLogger: NativeLoggingTool, serviceLogger: ServiceLoggingTool) => { // 根据环境变量决定使用组合类还是单一实现 if (process.env.NODE_ENV === 'staging') { return new CompositeLoggingTool([nativeLogger, serviceLogger]); } // 生产环境用ServiceLoggingTool,开发环境用NativeLoggingTool return process.env.NODE_ENV === 'production' ? serviceLogger : nativeLogger; }, inject: [NativeLoggingTool, ServiceLoggingTool], }, ], exports: [LoggingTool], }) export class LoggerModule {}
方案优势
- 严格遵循DRY原则:完全复用原有类的日志逻辑,无重复代码
- 符合开闭原则:新增日志实现时,只需将实例加入组合类数组,无需修改现有代码
- 适配NestJS生态:保持
this.loggingTool.debug(...)的原有使用方式,业务代码无需改动 - 环境切换灵活:通过环境变量轻松切换单一或组合日志实现
内容的提问来源于stack exchange,提问作者André
相关产品推荐
相关产品推荐

