如何在nestjs中正确使用工厂模式

问题描述 投票:0回答:2

在Nestjs中,我有一个模块,它使用useFactory动态创建基于configValue的类

该模块中没有专门的服务,而是返回一个依赖于配置的服务,因此DriverService1和DriverService2将一起构建

export const createFactory = (config: IConfig):Provider<IService> => {
    return {
        provide: 'FACTORY',
        useFactory: (service1: DriverService1, service2: DriverService2): IService => {
            if (config.driver == 'DriverService1')
            {
                return service1;
            }
            else if (config.driver == 'DriverService2')
            {
                return service2;
            }
            throw new Error('not implemented')
        },
        inject: [ DriverService1, DriverService2 ],
    }
};

@Module({})
export class MyModule {
    static register(config?: IConfig): DynamicModule {
        const factory = createFactory(config)
        return {
            module: MyModule,
            providers: [
                {
                   provide: 'CONFIG',
                   useValue: config,
                },
                DriverService1,
                DriverService2,
                factory
            ],
            exports: [factory],
        };
    }
}

但我不确定这是正确的方法

或者我应该在这个模块中创建一个专用服务,例如“MyModuleService”,然后在服务中执行工厂模式?驱动程序仅在使用时才会构造



interface IDriver {
    action1():void
    action2():void
    action3():void
}

class Driver1 implements IDriver{
    public action1():void {
        console.log("DriverService1 action1")
    }
    public action2():void {
        console.log("DriverService1 action2")
    }
    public action3():void {
        console.log("DriverService1 action3")
    }
}

class Driver2 implements IDriver{
    public action1():void {
        console.log("DriverService2 action1")
    }
    public action2():void {
        console.log("DriverService2 action2")
    }
    public action3():void {
        console.log("DriverService2 action3")
    }
}


export const createFactory = (config: IConfig):Provider<MyModuleSerice> => {
    return {
        provide: 'BROKER_FACTORY',
        useFactory: (service:MyModuleSerice): MyModuleSerice => {

            if (config.driver == 'Driver1')
            {
                service.setDriver(new Driver1());
            }
            else if (config.driver == 'Driver2')
            {
                service.setDriver(new Driver2());
            }
            else{
                throw new Error('not implemented')
            }
            return service
        },
        inject: [ MyModuleSerice ],
    }
};


@Module({})
export class MyModule {
    static register(config?: IConfig): DynamicModule {
        const facotry = createFactory(config)
        return {
            module: MyModule,
            providers: [
                {
                    provide: 'CONFIG',
                    useValue: config,
                },
                facotry
            ],
            exports: [facotry],
        };
    }
}

@Injectable()
class MyModuleSerice {
    protected driver:IDriver
    constructor() {
    }

    public setDriver(driver:IDriver) {
        this.driver = driver
    }
    
    public doSomething():void {
        this.driver.action1()
        this.driver.action2()
    }

    public doSomething2():void {
        this.driver.action1()
        this.driver.action3()
    }
}

nestjs factory-pattern solid-principles
2个回答
1
投票

这就是提供商发挥作用的地方。您可以创建一个可以为您处理此逻辑的自定义提供程序。见下文。

https://docs.nestjs.com/fundamentals/custom-providers

这是 NestJS 提供的示例,它利用配置文件来创建服务实例。

 const configServiceProvider = {
  provide: ConfigService,
  useClass:
    process.env.NODE_ENV === 'development'
      ? DevelopmentConfigService
      : ProductionConfigService,
};

@Module({
  providers: [configServiceProvider],
})
export class AppModule {}

0
投票

让我们首先了解两种方法之间的区别,然后再确定哪种方法更好。

  1. 方法 1:您已经创建了一个模块,它将根据提供的配置提供驱动程序实例。这可以被认为是一个 DriverFactoryModule。

  2. 方法 2:您创建了一个模块,该模块返回一个封装驱动程序实例的服务(基于提供的配置),主要目的是提供执行可以使用驱动程序实例执行的操作的功能。这种方法不会公开驱动程序实例本身。

在这两种方法中,您打算使用工厂模式根据用户的需求创建驱动程序实例。然而,工厂模式的实现依赖于抽象,即工厂类依赖于接口或抽象,并根据用户的请求创建具体的实例。在实现方面,工厂模式实现在第二种方法中遵循了这一原则。您可以通过更改命名约定来进行另一项改进(例如,DriverFactory 服务(模块内部)使用方法“getDriverInstance”,该方法扮演工厂的角色并在提供程序内部使用它:(userFactory))。

那么,现在让我们来讨论主要问题 - 哪种方法更好?这完全取决于模块的预期。模块应该只返回驱动程序实例还是应该返回封装驱动程序实例的 DriverService

© www.soinside.com 2019 - 2024. All rights reserved.