关于javascript:避免修改构造函数输入参数引起的-breaking-change

221次阅读

共计 1383 个字符,预计需要花费 4 分钟才能阅读完成。

本文记录我在工作中的一次失误。

如下图所示,我在构造函数里注入了一个新的依赖:

protected checkoutService: CheckoutService

当下列状况同时满足时,客户就会遇到编译谬误:

(1) 客户降级到了新的 minor 版本,即我引入该新的依赖的版本。
(2) 客户之前扩大了 CheckoutDeliveryService
(3) 客户在本人的扩大类的构造函数里,调用了 super 即父类的构造函数。

因为客户是从旧版本升级上来的,所以构造函数里没有传递我这个新版本引入的 checkoutService 输出参数,所以会遇到语法错误。

正确的做法如下图所示:

export class CheckoutDeliveryService implements CheckoutDeliveryFacade {
  constructor(
    protected checkoutStore: Store<StateWithCheckout>,
    protected processStateStore: Store<StateWithProcess<void>>,
    protected activeCartService: ActiveCartService,
    protected userIdService: UserIdService,
    @Optional() protected checkoutService?: CheckoutService) {}

应用 @Optional 来润饰这个新引入的构造函数输出参数。

同时,在代码里的逻辑也须要扭转,须要同时解决 checkoutService 为空或者不为空的状况。

  protected isCheckoutDetailsLoading$: Observable<boolean> = this
    .checkoutService
    ? this.checkoutService.isLoading()
    : this.checkoutStore.pipe(select(CheckoutSelectors.getCheckoutLoading));

如果 checkoutService 不为空,则应用 checkoutService.isLoading 返回的 Observable;否则,就为旧版本的状况,应用旧版本的实现,从 checkoutStore 里取出 checkout loading 的读取状态。

批改了服务代码之后,也会影响到对应的单元测试代码。

现在的 isSetDeliveryModeBusy 标记位,决定其值的输出条件之二,从 checkoutService.isLoading, 更改成了 isCheckoutDetailsLoading.

因而,在单元测试代码里,咱们须要创立一个全局的 isCheckoutLoading$ Observable 对象:

而后创立一个 mockCheckoutService 类,外部返回这个全局的 isCheckoutLoading$ Observable 对象。

这样,在任何时候咱们须要批改 CheckoutService.isLoading 的返回值时,通过调用 isCheckoutLoading$ 的 next 办法即可灵便管制。

须要强调的是,在大型 API 中放弃稳定性是一项挑战。如果您要更改 API 库,请思考更改的宽泛结果,并尝试预测可能呈现的任何问题。

更多 Jerry 的原创文章,尽在:” 汪子熙 ”.

正文完
 0