重构Angular+Node项目中认知复杂度超标的支付处理函数
重构Angular+Node项目中认知复杂度超标的支付处理函数
兄弟,我太懂你被一堆嵌套if-else绕得晕头转向的感觉了——认知复杂度超标不仅看着闹心,后续改需求加新支付方式的时候简直是噩梦。不过别慌,咱们用策略模式来重构这段代码,既能把逻辑捋得明明白白,还完全不会影响调用这个方法的其他代码,毕竟只是内部实现变了,对外的接口半点儿没变。
先拆解原代码的核心问题
你这段代码里重复出现了!orderRequest.paymentProvider || isAdyenProvider的判断,而且每个分支都是「匹配支付提供商+支付方式 → 执行对应处理逻辑」的模式,这种链式if-else最容易拉高认知复杂度。
重构方案:用策略映射表替代if-else链
咱们把每个条件和对应的处理逻辑封装成一个个「策略对象」,然后用一个映射表来管理,最后只需要找到匹配的策略执行就行。
第一步:提前简化重复判断
先把重复的Adyen判断抽出来,只计算一次:
const isAdyen = !orderRequest.paymentProvider || isAdyenProvider;
第二步:定义支付处理策略映射表
把每个分支的条件和处理逻辑对应起来,形成一个数组:
// 定义支付策略数组,每个元素对应原代码的一个if-else分支 const paymentStrategies = [ { match: () => isAdyen && orderRequest.paymentMethod === OrderRequestV2.PaymentMethodEnum.CREDITCARD, handler: () => this.processPaymentGiftCard( basket, constants.PAYMENT_METHODS.CREDIT_CARD, constants.PAYMENT_METHODS.GIFT_CERTIFICATE, 'AdyenCreditCardPaymentMethodService' ) }, { match: () => isAdyen && orderRequest.paymentMethod === OrderRequestV2.PaymentMethodEnum.PAYPAL, handler: () => this.processPaymentGiftCard( basket, constants.PAYMENT_METHODS.ADYEN_PAYPAL, constants.PAYMENT_METHODS.GIFT_CERTIFICATE, 'adyenPayPalPaymentMethodService' ) }, { match: () => isAdyen && orderRequest.paymentMethod === OrderRequestV2.PaymentMethodEnum.INVOICE, handler: () => this.processPaymentGiftCard( basket, constants.PAYMENT_METHODS.INVOICE, constants.PAYMENT_METHODS.GIFT_CERTIFICATE, 'AdyenInvoicePaymentMethodService' ) }, { match: () => orderRequest.paymentProvider === OrderRequestV2.PaymentProviderEnum.COD && orderRequest.paymentMethod === OrderRequestV2.PaymentMethodEnum.COD, handler: () => this.processPayment( basket, constants.PAYMENT_METHODS.CREDIT_CARD, 'GMOCreditCardPaymentMethodService' ) }, { match: () => isAdyen && orderRequest.paymentMethod === OrderRequestV2.PaymentMethodEnum.GIFTCERTIFICATE, handler: async () => { const giftCardPaymentInstruments = await this.pickPaymentInstruments( basket, constants.PAYMENT_METHODS.GIFT_CERTIFICATE, true ); return this.getGiftCardsPayments(giftCardPaymentInstruments); } }, { match: () => isAdyen && orderRequest.paymentMethod === OrderRequestV2.PaymentMethodEnum.APPLEPAY, handler: () => this.processPayment( basket, constants.PAYMENT_METHODS.APPLE_PAY, 'AdyenApplePayPaymentService' ) }, { match: () => isAdyen && orderRequest.paymentMethod === OrderRequestV2.PaymentMethodEnum.SHOPRUNNER, handler: () => this.processPayment( basket, constants.PAYMENT_METHODS.CREDIT_CARD, 'AdyenShoprunnerPaymentService' ) } ];
第三步:匹配并执行策略
只需要找到第一个符合条件的策略,执行它的处理逻辑就行:
// 找到第一个匹配的支付策略 const matchedStrategy = paymentStrategies.find(strategy => strategy.match()); if (matchedStrategy) { // 执行对应逻辑,异步分支的Promise会自动传递,和原代码行为一致 return matchedStrategy.handler(); } // 如果原代码有默认分支(比如无匹配时的处理),可以在这里补充
这个方案的好处
- 完全兼容原有调用方:方法的入参、返回值和原代码完全一致,外部代码不需要做任何修改
- 可读性拉满:一眼就能看到每个支付方式对应的处理逻辑,不用再嵌套翻找
- 维护成本降低:后续新增支付方式,只需要在策略数组里加一条,不用动原来的逻辑
- 消除重复判断:
isAdyen只计算一次,避免了冗余的条件检查
备注:内容来源于stack exchange,提问作者user5798214
相关产品推荐
相关产品推荐

