策略模式教程

news/2024/11/5 14:53:40/

策略模式是一种行为型设计模式,它允许在运行时根据不同的情况选择不同的算法实现,从而使得算法可以独立于客户端而变化。本文将介绍策略模式的概念、应用场景、优点和缺点,并提供最佳的代码实践。本文的代码实现将使用Java语言,但是策略模式同样适用于其他编程语言。

概念

策略模式定义了一系列算法,并将每个算法封装成一个类,使得它们可以互相替换。策略模式让算法的变化独立于使用它们的客户端,从而实现了算法和客户端之间的松耦合关系。策略模式通常包含三个角色:上下文(Context)、策略(Strategy)和具体策略(ConcreteStrategy)。

  • 上下文(Context):定义了客户端所需要的接口,并维护一个对策略对象的引用。

  • 策略(Strategy):定义了一个公共的接口,用于所有具体策略的替换。

  • 具体策略(ConcreteStrategy):实现了策略接口,并提供了一种具体的算法实现。

应用场景

策略模式适用于以下场景:

  • 当需要在运行时根据不同的情况选择不同的算法实现时。

  • 当一个算法有多个变体时,可以将它们封装成不同的具体策略。

  • 当一个类中有很多条件语句时,可以考虑使用策略模式来消除这些条件语句。

优点和缺点

策略模式的优点在于它可以提高代码的可维护性、可扩展性和可复用性,使得算法的变化对客户端的影响最小化。同时,策略模式还符合开闭原则,即对扩展开放,对修改关闭,当需要添加新的算法时,只需要增加一个新的具体策略即可,而不需要修改原有的代码。策略模式的缺点在于它会增加代码的复杂度,因为需要定义多个策略类和上下文类。同时,策略模式还可能会导致客户端代码变得复杂,因为客户端需要了解不同的策略类和它们的区别,从而选择合适的策略。

最佳实践

下面是一个策略模式的示例代码,它模拟了一个商品打折的场景。假设一个商店需要根据不同的季节和VIP等级来对商品进行不同的打折,我们可以使用策略模式来实现这个场景。首先,我们定义一个商品类,它包含了商品的名称和价格。

public class Product {private String name;private double price;public Product(String name, double price) {this.name = name;this.price = price;}public String getName() {return name;}public double getPrice() {return price;}
}

然后,我们定义一个策略接口,它包含了一个方法用于计算打折后的价格。

public interface DiscountStrategy {double getDiscountedPrice(Product product);
}

接下来,我们实现三个具体策略类,分别表示不打折、季节折扣和VIP折扣。

public class NoDiscountStrategy implements DiscountStrategy {@Overridepublic double getDiscountedPrice(Product product) {return product.getPrice();}
}
public class SeasonDiscountStrategy implements DiscountStrategy {@Overridepublic double getDiscountedPrice(Product product) {return product.getPrice() * 0.9;}
}
public class VIPDiscountStrategy implements DiscountStrategy {@Overridepublic double getDiscountedPrice(Product product) {return product.getPrice() * 0.8;}
}

最后,我们定义一个上下文类,它包含了一个对策略对象的引用,并提供了一个方法用于计算打折后的价格。

public class ProductContext {private DiscountStrategy strategy;public void setStrategy(DiscountStrategy strategy) {this.strategy = strategy;}public double getDiscountedPrice(Product product) {return strategy.getDiscountedPrice(product);}
}

现在,我们可以在客户端代码中使用这些类来计算商品的打折价格了。

public class Main {public static void main(String[] args) {ProductContext context = new ProductContext();context.setStrategy(new NoDiscountStrategy());Product product1 = new Product("Product 1", 100.0);System.out.println("Original price: " + product1.getPrice());System.out.println("Discounted price: " + context.getDiscountedPrice(product1)); // 输出 100.0context.setStrategy(new SeasonDiscountStrategy());Product product2 = new Product("Product 2", 100.0);System.out.println("Original price: " + product2.getPrice());System.out.println("Discounted price: " + context.getDiscountedPrice(product2)); // 输出 90.0context.setStrategy(new VIPDiscountStrategy());Product product3 = new Product("Product 3", 100.0);System.out.println("Original price: " + product3.getPrice());System.out.println("Discounted price: " + context.getDiscountedPrice(product3)); // 输出 80.0}
}

在上面的代码中,我们首先创建了一个ProductContext对象,并设置了一个策略对象NoDiscountStrategy。然后,我们创建了一个商品Product对象,并通过ProductContext对象来计算打折后的价格。接着,我们分别设置SeasonDiscountStrategy和VIPDiscountStrategy作为策略对象,再次计算商品的打折价格。最后,我们输出了原价和打折后的价格。这样,我们就使用策略模式实现了商品打折的场景。如果需要添加新的打折策略,只需要实现一个新的具体策略类并在客户端代码中设置即可,而不需要修改原有的代码。


http://www.ppmy.cn/news/31798.html

相关文章

C++经典15道面试题目(文末含大题)

今天给大家找了几个C面试里很有可能被问的哦,赶紧收藏下来去背!!! 目录 1)C中有malloc/free,为什么还需要new/delete? 2)C中explicit关键字的作用? 3)C中static关键字的作用&a…

自然语言处理中数据增强(Data Augmentation)技术最全盘点

与“计算机视觉”中使用图像数据增强的标准做法不同,在NLP中,文本数据的增强非常少见。这是因为对图像的琐碎操作(例如将图像旋转几度或将其转换为灰度)不会改变其语义。语义上不变的转换的存在是使增强成为Computer Vision研究中…

【Linux】旋转锁 | 读写锁

在之前的线程学习中,用到的锁都是挂起等待锁,如果申请不到锁,那就会在锁中等待; 自旋锁则不大相似 文章目录1.自旋锁1.1 概念1.2 接口1.2.1 pthread_spin_init/destroy1.2.2 pthread_spin_lock1.2.3 pthread_spin_unlock2.读写锁…

引出生命周期、生命周期_挂载流程、生命周期_更新流程、生命周期_销毁流程、生命周期_总结——Vue

目录 一、引出生命周期 二、生命周期_挂载流程 三、生命周期_更新流程 四、生命周期_销毁流程 五、生命周期_总结 一、引出生命周期 生命周期: 1.又名:生命周期回调函数、生命周期函数、生命周期钩子。 2.是什么:Vue在关键时刻帮我们调…

华为云arm架构轻松安装kubeedge

先安装k8s 华为云arm架构安装k8s(kubernetes) 下载kubeedge需要的软件 官方github下载kubeedge地址 cloudcore.service文件下载地址 注意:下载对应的版本和arm架构 keadm-v1.6.1-linux-arm64.tar.gz 下面的2个文件可以不用下载,安装kubeedge时也会自动去下载到/etc/kubee…

从零开始的JSON库(1):启程

1. JSON 是什么 JSON(JavaScript Object Notation)是一个用于数据交换的文本格式,现时的标准为ECMA-404 。 虽然 JSON 源自于 JavaScript 语言,但它只是一种数据格式,可用于任何编程语言。现时具有类似功能的格式有X…

Web学习3_JavaScript

1.1 JS的调用方式与执行顺序 使用方式 HTML页面中的任意位置加上<script type"module"></script>标签即可。 常见使用方式有以下几种&#xff1a; 直接在<script type"module"></script>标签内写JS代码。script type"modu…

【C++学习】类和对象(上)

前言&#xff1a; 由于之前电脑“嗝屁”了&#xff0c;导致这之前一直没有更新博客&#xff0c;今天才拿到电脑&#xff0c;在这里说声抱歉。接下来就进入今天的学习&#xff0c;在之前我们已经对【C】进行了初步的认识&#xff0c;有了之前的知识铺垫&#xff0c;今天我们将来…