避免修改构造函数输入参数引起的 breaking change

举报
Jerry Wang 发表于 2022/10/03 10:09:52 2022/10/03
【摘要】 本文记录我在工作中的一次失误。如下图所示,我在构造函数里注入了一个新的依赖:protected checkoutService: CheckoutService当下列情况同时满足时,客户就会遇到编译错误:(1) 客户升级到了新的 minor 版本,即我引入该新的依赖的版本。(2) 客户之前扩展了 CheckoutDeliveryService(3) 客户在自己的扩展类的构造函数里,调用了 s...

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

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

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 库,请考虑更改的广泛后果,并尝试预测可能出现的任何问题。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。