策略模式
link:⚛️ Applying Design Patterns in React: Strategy Pattern - DEV Community 👩‍💻👨‍💻
code: Loading… - CodeSandbox

对于共享和公共的逻辑抽离成一个 抽象类,然后不同的逻辑需要继承并实现该抽象类,抽象类代码如下

import { Country, Currency } from '../../types';
 
abstract class PriceStrategy {
  protected country: Country = Country.AMERICA;
  protected currency: Currency = Currency.USD;
  protected discountRatio = 0;
 
  getCountry(): Country {
    return this.country;
  }
 
  formatPrice(price: number): string {
    return [this.currency, price.toLocaleString()].join('');
  }
 
  getDiscountAmount(price: number): number {
    return price * this.discountRatio;
  }
 
  getFinalPrice(price: number): number {
    return price - this.getDiscountAmount(price);
  }
 
  shouldDiscount(): boolean {
    return this.discountRatio > 0;
  }
 
  getDiscountMessage(price: number): string {
    const formattedDiscountAmount = this.formatPrice(
      this.getDiscountAmount(price)
    );
 
    return `It's lucky that you come from ${this.country}, because we're running a program that discounts the price by ${formattedDiscountAmount}.`;
  }
}
 
export default PriceStrategy;

不同的业务逻辑继承并实现该抽象类

A 逻辑:

import PriceStrategy from './PriceStrategy';
import { Country, Currency } from '../../types';
 
class JapanPriceStrategy extends PriceStrategy {
	constructor() {
		super();
		this.country = Country.JAPAN;
		this.currency = Currency.YEN;
		this.discountRatio = 0.2;
	}
 
	getDiscountMessage(price: number): string {
		const formattedDiscountAmount = this.formatPrice(
		this.getDiscountAmount(price)
	);
 
		return `We have discounted the price by ${formattedDiscountAmount} thanks to the support from Japan's government.`;
	}
}
 
export default JapanPriceStrategy;
 

B 逻辑

import PriceStrategy from './PriceStrategy';
import { Country, Currency } from '../../types';
 
class VietnamPriceStrategy extends PriceStrategy {
	constructor() {
		super();
		this.country = Country.VIETNAM;
		this.currency = Currency.VND;
		this.discountRatio = 0.4;
	}
 
	formatPrice(price: number) {
		return [price.toLocaleString(), Currency.VND].join(' ');
	}
 
	getDiscountMessage(price: number): string {
		const formattedDiscountAmount = this.formatPrice(
		this.getDiscountAmount(price)
	);
 
		return `The price has been discounted by ${formattedDiscountAmount} because you come from Vietnam.`;
	}
}
 
export default VietnamPriceStrategy;

最后只需要将实例话的策略作为Props传递给我们的组件

<PricingCard price={7669} strategy={new JapanPriceStrategy()} />

策略模式与普通模式的对比

普通模式:

策略模式: