Angular 和 Typescript 的策略模式

Nen*_*adP 5 design-patterns typescript angular

我想在 Angular/Typescript 中实现策略模式并在组件中使用服务;服务采用策略接口作为构造函数参数。此外,约束是服务依赖于角度级别上的一些其他注入服务。

我正在深入研究文档,但无法找到一种方法来做到这一点。我不希望最终出现过度设计的代码,而是寻找简单的解决方案来实现策略模式。

请参阅下面的模拟代码:

export interface IStrategy {
    calculate(a,b): number;
}

export class MinusStrategy implements IStrategy {
    calculate(a,b): number {
        return a - b;
    }
}

export class PlusStrategy implements IStrategy {
    calculate(a,b): number {
        return a + b;
    }
}

@Injectable() 
export class CalculatorService {
    // I understand it is not possible to have DI of the Interface here for calcStrategy 
    constructor(private http: HttpClient; private calcStrategy: IStrategy);
    
    getByCalc() {
        this.http.get('someurl?calc=' + calcStrategy.calculate(1,1));
    }
}

@Component(// skipped config here...)
export class MyComponent implements OnInit {
    // How to inject appropriate concrete strategy (and either autowire or provide httpClient?)
    constructor(private service: new CalculatorService(httpClient, new MinusStrategy()));
    
    useInComponent() {
        this.service.getByCalc();
    }
}

Run Code Online (Sandbox Code Playgroud)

eol*_*eol 1

一种方法是定义自定义注入令牌并在组件提供程序声明中使用此令牌(请参阅https://angular.io/guide/dependency-injection-in-action#supply-a-custom-provider- with-inject了解更多信息):

export const CalculatorStrategy = new InjectionToken<string>('CalculatorStrategy');

@Component({
    providers: [
        // define the actual strategy-implementation here, setting it as `useClass`-provider
        {provide: CalculatorStrategy, useClass: PlusStrategy}
    ]
})
export class MyComponent implements OnInit {
    
    constructor(private service: CalculatorService) {
    }

    useInComponent() {
        this.service.getByCalc();
    }
}

@Injectable()
export class CalculatorService {

    constructor(private http: HttpClient, @Inject(CalculatorStrategy) private calcStrategy: IStrategy);

    getByCalc() {
        this.http.get('someurl?calc=' + this.calcStrategy.calculate(1, 1));
    }
}
Run Code Online (Sandbox Code Playgroud)