当前位置: 首页 > news >正文

常用设计模式:策略模式

策略模式(Strategy Pattern)是一种行为设计模式,它允许你定义一系列算法,并将每个算法封装起来,使它们可以相互替换。下面介绍策略模式在 TypeScript 中的实现。

策略模式基本概念

策略模式包含三个主要部分:

Context(上下文):维护一个策略对象的引用

Strategy(策略接口):定义所有支持的算法的公共接口

ConcreteStrategy(具体策略):实现策略接口的具体算法

image

基础实现

1. 定义策略接口

// 策略接口

interface PaymentStrategy {

pay(amount: number): void;

}

2. 实现具体策略类

// 信用卡支付策略

class CreditCardPayment implements PaymentStrategy {

private cardNumber: string;

private name: string;

constructor(cardNumber: string, name: string) {

this.cardNumber = cardNumber;

this.name = name;

}

pay(amount: number): void {

console.log(`使用信用卡支付 $${amount}`);

console.log(`卡号: ${this.cardNumber}, 持卡人: ${this.name}`);

}

}

// PayPal支付策略

class PayPalPayment implements PaymentStrategy {

private email: string;

constructor(email: string) {

this.email = email;

}

pay(amount: number): void {

console.log(`使用PayPal支付 $${amount}`);

console.log(`邮箱: ${this.email}`);

}

}

// 加密货币支付策略

class CryptoPayment implements PaymentStrategy {

private walletAddress: string;

constructor(walletAddress: string) {

this.walletAddress = walletAddress;

}

pay(amount: number): void {

console.log(`使用加密货币支付 $${amount}`);

console.log(`钱包地址: ${this.walletAddress}`);

}

}

3. 创建上下文类

// 支付上下文

class PaymentContext {

private strategy: PaymentStrategy;

constructor(strategy: PaymentStrategy) {

this.strategy = strategy;

}

// 设置支付策略

setStrategy(strategy: PaymentStrategy): void {

this.strategy = strategy;

}

// 执行支付

executePayment(amount: number): void {

this.strategy.pay(amount);

}

}

4. 使用示例

// 使用示例

const paymentContext = new PaymentContext(new CreditCardPayment("1234-5678-9012", "张三"));

// 使用信用卡支付

paymentContext.executePayment(100);

// 切换到PayPal支付

paymentContext.setStrategy(new PayPalPayment("zhang@example.com"));

paymentContext.executePayment(200);

// 切换到加密货币支付

paymentContext.setStrategy(new CryptoPayment("1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa"));

paymentContext.executePayment(300);

更复杂的示例:排序策略

// 排序策略接口

interface SortStrategy<T> {

sort(items: T[]): T[];

}

// 冒泡排序策略

class BubbleSort<T> implements SortStrategy<T> {

sort(items: T[]): T[] {

console.log("使用冒泡排序");

const arr = [...items];

for (let i = 0; i < arr.length; i++) {

for (let j = 0; j < arr.length - i - 1; j++) {

if (arr[j] > arr[j + 1]) {

[arr[j], arr[j + 1]] = [arr[j + 1], arr[j]];

}

}

}

return arr;

}

}

// 快速排序策略

class QuickSort<T> implements SortStrategy<T> {

sort(items: T[]): T[] {

console.log("使用快速排序");

if (items.length <= 1) return items;

const pivot = items[0];

const left = [];

const right = [];

for (let i = 1; i < items.length; i++) {

if (items[i] < pivot) {

left.push(items[i]);

} else {

right.push(items[i]);

}

}

return [...this.sort(left), pivot, ...this.sort(right)];

}

}

// 排序上下文

class Sorter<T> {

private strategy: SortStrategy<T>;

constructor(strategy: SortStrategy<T>) {

this.strategy = strategy;

}

setStrategy(strategy: SortStrategy<T>): void {

this.strategy = strategy;

}

sort(items: T[]): T[] {

return this.strategy.sort(items);

}

}

// 使用示例

const numbers = [64, 34, 25, 12, 22, 11, 90];

const sorter = new Sorter<number>(new BubbleSort<number>());

console.log("排序前:", numbers);

console.log("排序后:", sorter.sort(numbers));

// 切换排序策略

sorter.setStrategy(new QuickSort<number>());

console.log("使用快速排序:", sorter.sort(numbers));

使用函数式编程的实现

TypeScript 也支持函数式风格的策略模式:

// 策略类型定义

type DiscountStrategy = (amount: number) => number;

// 具体策略函数

const noDiscount: DiscountStrategy = (amount: number) => amount;

const percentageDiscount = (percentage: number): DiscountStrategy =>

(amount: number) => amount * (1 - percentage / 100);

const fixedDiscount = (discount: number): DiscountStrategy =>

(amount: number) => Math.max(0, amount - discount);

// 上下文

class ShoppingCart {

private items: number[] = [];

private discountStrategy: DiscountStrategy = noDiscount;

addItem(price: number): void {

this.items.push(price);

}

setDiscountStrategy(strategy: DiscountStrategy): void {

this.discountStrategy = strategy;

}

getTotal(): number {

const subtotal = this.items.reduce((sum, price) => sum + price, 0);

return this.discountStrategy(subtotal);

}

}

// 使用示例

const cart = new ShoppingCart();

cart.addItem(100);

cart.addItem(50);

cart.addItem(30);

console.log("原价:", cart.getTotal()); // 180

cart.setDiscountStrategy(percentageDiscount(10)); // 9折

console.log("9折后:", cart.getTotal()); // 162

cart.setDiscountStrategy(fixedDiscount(50)); // 减50

console.log("减50后:", cart.getTotal()); // 130

策略模式的优点

开闭原则:可以引入新策略而不修改现有代码

消除条件语句:避免大量的 if-else 或 switch-case 语句

算法复用:可以在不同的上下文中复用策略

测试友好:每个策略都可以独立测试

http://www.cnnetsun.cn/news/48745.html

相关文章:

  • CogVideo革命性突破:2D视频秒变立体3D的智能转换技术
  • DeepLabCut实战进阶:从姿态估计到强化学习环境的深度配置指南
  • 终极游戏DLC解锁指南:三步免费解锁付费内容
  • SeedVR2 2.5.10全面评测:8GB显存也能玩转的AI视觉增强神器
  • PCSX2模拟器性能优化终极指南:从卡顿到流畅的完整解决方案
  • 告别卡顿:DBeaver性能优化终极指南
  • NetSonar网络诊断工具:快速定位网络问题的终极解决方案
  • 电子书格式不兼容 零门槛转换 一键搞定 电子书格式转换下载器
  • 『一键掌控』Defender Control:Windows安全防护的终极管理方案
  • 如何在3小时内构建28M微模型:数据预处理实战避坑指南
  • Wallpaper Engine壁纸下载器:5分钟学会轻松获取创意工坊动态壁纸
  • 250MB实现千亿级能力:腾讯混元0.5B重构边缘AI范式
  • HunyuanVideo-Avatar:单图+音频生成高保真数字人视频,开启内容创作新纪元
  • MATLAB 2008B完整安装指南:从下载到配置的一站式解决方案
  • 计算机毕业设计|基于springboot + vue图书借阅管理系统(源码+数据库+文档)
  • FLUX Kontext革命:AI图像编辑如何让普通人秒变设计高手
  • PyTorch 多卡训练常见坑:设置 CUDA_VISIBLE_DEVICES 后仍 OOM 在 GPU 0 的解决之道
  • 基于vue的线上商城购物系统_q90ol4sn_springboot php python nodejs
  • MPV播放器窗口管理终极指南:从零掌握精确定位技巧
  • DFT + SUMO + GALORE = DFT模拟实验光谱效果
  • 31、Ubuntu 网络配置全攻略
  • Sparklines:如何在3分钟内为你的数据监控系统添加可视化能力
  • 29、Ubuntu系统下数字设备与音视频使用全攻略
  • 34、Linux系统的文件共享与安全防护指南
  • 37、Ubuntu社区交流、资讯获取及常见问题解决指南
  • 40、Ubuntu系统常见问题及解决方法
  • 42、Ubuntu硬盘手动分区及相关资源指南
  • 超强音频机器人实战指南:让你的TeamSpeak服务器秒变音乐厅
  • LMMS音乐制作完全指南:从入门到精通的免费创作平台
  • 云原生监控实战:5分钟构建高可用可观测性平台