news 2026/3/30 17:20:02

常用设计模式:策略模式

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
常用设计模式:策略模式

策略模式(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 语句

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

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

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/3/29 2:37:12

如何快速掌握1Panel批量操作:多服务器一键管理终极技巧

如何快速掌握1Panel批量操作&#xff1a;多服务器一键管理终极技巧 【免费下载链接】1Panel 项目地址: https://gitcode.com/GitHub_Trending/1p/1Panel 还在为管理多台服务器而头疼吗&#xff1f;每次都要重复登录、执行相同命令&#xff0c;效率低下还容易出错&#…

作者头像 李华
网站建设 2026/3/26 6:49:16

游戏开发入门完全指南:从零开始掌握游戏编程技能

游戏开发入门完全指南&#xff1a;从零开始掌握游戏编程技能 【免费下载链接】books o armazm de livros 项目地址: https://gitcode.com/GitHub_Trending/boo/books 想要学习游戏开发却不知道从哪里开始&#xff1f;GitHub_Trending/boo/books项目为你提供了一条清晰的…

作者头像 李华
网站建设 2026/3/26 9:04:32

2025年CLIP模型进化:从跨模态基石到工业质检新范式

2025年CLIP模型进化&#xff1a;从跨模态基石到工业质检新范式 【免费下载链接】clip-vit-base-patch16 项目地址: https://ai.gitcode.com/hf_mirrors/openai/clip-vit-base-patch16 导语 OpenAI于2021年推出的CLIP模型正迎来技术爆发期&#xff0c;2025年最新研究通…

作者头像 李华
网站建设 2026/3/27 8:07:09

5个真实案例揭秘DolphinScheduler:企业级任务调度如何轻松搞定数据工作流

5个真实案例揭秘DolphinScheduler&#xff1a;企业级任务调度如何轻松搞定数据工作流 【免费下载链接】dolphinscheduler Dolphinscheduler是一个分布式调度系统&#xff0c;主要用于任务调度和流程编排。它的特点是易用性高、可扩展性强、性能稳定等。适用于任务调度和流程自动…

作者头像 李华
网站建设 2026/3/25 2:33:11

关于计算机语言的学习

在这个系列的笔记中&#xff0c;我将记录下自己在学习计算机语言的过程中所积累的一些心得体会&#xff0c;笔记的内容将会包括我对编程语言、标记语言的了解&#xff0c;以及我学习各种语言的具体过程。希望这些笔记能够帮助到那些对编程语言感兴趣的朋友们。下面是这一系列学…

作者头像 李华