电影院售票 - 策略模式(Strategy Pattern)

server/2025/1/8 0:47:37/

策略模式(Strategy Pattern)

策略模式(Strategy Pattern)

策略模式(Strategy Pattern)是一种行为型设计模式,它定义了一系列算法,并将每个算法封装起来,使它们可以相互替换。策略模式让算法独立于使用它的客户端而变化,从而提高了代码的灵活性和可维护性。

太抽象了
还是举个现实生活中的例子,假如我们现在要设计一个电影院售票系统,我们要给不同的客户提供不同的折扣,比如说:老年人半价,学生票半价,小朋友多少岁之前免票之类的。怎么办?你可能像,我们直接if else不就好了。也许开始的时候是可以实现我们的要求的,但是如果我们现在要增加活动,学生积分抵现,或者看5次免一次票价活动,你想想我们如果要在之前的ifelse里面做改动的话,会导致修改的量很大,而且还非常容易出错。那有没有更好的实现方式呢? 策略模式(Strategy Pattern)

策略模式概述

策略模式结构图

在这里插入图片描述

策略模式主要包含的角色

  1. 策略接口(Strategy):定义了所有支持算法公共操作的接口或抽象类。具体策略类必须实现这个接口中的方法。
java">public interface Strategy {void execute();
}
  1. 具体策略(ConcreteStrategy):实现了 Strategy 接口的具体类。每个具体策略都提供了一种算法的实现方式。
java">public class ConcreteStrategyA implements Strategy {@Overridepublic void execute() {System.out.println("strategy A");}
}public class ConcreteStrategyB implements Strategy {@Overridepublic void execute() {System.out.println("strategy B");}
}
  1. 上下文(Context):上下文类拥有一个对策略对象的引用,并提供了设置和获取策略的方法。上下文委托给策略对象来执行具体的算法逻辑。
java">public class Context {private Strategy strategy;// 设置策略public void setStrategy(Strategy strategy) {this.strategy = strategy;}// 执行策略public void executeStrategy() {if (strategy != null) {strategy.execute();} else {System.out.println("Strategy not set");}}
}

talk is cheap, show you my code

java">// 策略接口
interface PricingStrategy {double calculatePrice(double basePrice);
}// 成人票价策略
class AdultPricingStrategy implements PricingStrategy {@Overridepublic double calculatePrice(double basePrice) {// 假设成人票价没有折扣return basePrice;}
}// 儿童票价策略
class ChildPricingStrategy implements PricingStrategy {@Overridepublic double calculatePrice(double basePrice) {// 假设儿童票价是半价return basePrice / 2;}
}// 学生票价策略
class StudentPricingStrategy implements PricingStrategy {@Overridepublic double calculatePrice(double basePrice) {// 假设学生票价有8折优惠return basePrice * 0.8;}
}// 电影票类
class MovieTicket {private String movieName;private double basePrice;private PricingStrategy pricingStrategy;public MovieTicket(String movieName, double basePrice, PricingStrategy pricingStrategy) {this.movieName = movieName;this.basePrice = basePrice;this.pricingStrategy = pricingStrategy;}public double getPrice() {return pricingStrategy.calculatePrice(basePrice);}@Overridepublic String toString() {return "MovieTicket{" +"movieName='" + movieName + '\'' +", price=" + getPrice() +'}';}
}// 客户端类
public class CinemaTicketingSystem {public static void main(String[] args) {double basePrice = 100.0; // 假设基础票价为100元// 创建不同的票价策略PricingStrategy adultStrategy = new AdultPricingStrategy();PricingStrategy childStrategy = new ChildPricingStrategy();PricingStrategy studentStrategy = new StudentPricingStrategy();// 创建电影票对象MovieTicket adultTicket = new MovieTicket("Inception", basePrice, adultStrategy);MovieTicket childTicket = new MovieTicket("Inception", basePrice, childStrategy);MovieTicket studentTicket = new MovieTicket("Inception", basePrice, studentStrategy);// 打印票价System.out.println(adultTicket); // MovieTicket{movieName='Inception', price=100.0}System.out.println(childTicket);  // MovieTicket{movieName='Inception', price=50.0}System.out.println(studentTicket); // MovieTicket{movieName='Inception', price=80.0}}
}

在这个例子中,PricingStrategy接口定义了计算票价的方法。AdultPricingStrategy、ChildPricingStrategy和StudentPricingStrategy类分别实现了这个接口,并提供了不同的计算逻辑。MovieTicket类有一个PricingStrategy类型的成员变量,用于存储当前电影票所使用的票价策略。在getPrice方法中,它调用策略对象的calculatePrice方法来计算票价。

总结

策略模式的优点

  • 算法与客户端分离:通过将算法封装在独立的策略类中,使得算法的实现细节对客户端透明。
  • 易于扩展:新增加一种算法只需添加一个新的具体策略类,而不必修改现有的代码。
  • 符合开闭原则:当需要添加新的策略时,只需创建新的策略类,而不需要改变已有的代码。
  • 避免条件语句:使用策略模式可以减少代码中的条件判断语句,提高代码的清晰度和可读性。

策略模式缺点

  • 增加类的数量
  • 客户端需要知道所有的策略
  • 接口定义困难
  • 策略的组合与复用有限
  • 简单场景不建议使用策略模式

策略模式的应用场景

  • 不同支付方式:如现金、信用卡、支付宝等支付方式的选择可以通过策略模式来实现。
  • 排序算法:根据数据量大小选择不同的排序算法(快速排序、插入排序等),也可以用策略模式来管理。
  • 日志记录:不同的日志级别(DEBUG、INFO、ERROR等)可以有不同的处理方式,这些都可以作为策略来实现。
  • 游戏AI:在游戏中,NPC的行为可以根据玩家的动作或环境状态来动态调整,这也可以通过策略模式来实现。

策略模式是一个非常有用的设计模式,特别是在需要根据不同情况选择不同算法或行为的时候。它可以帮助我们更好地组织代码,提高系统的灵活性和可维护性。


http://www.ppmy.cn/server/156639.html

相关文章

实现自定义集合类:深入理解C#中的IEnumerable<T>接口

文章目录 介绍主要成员示例代码约束常见的约束类型示例代码介绍 在C#中,IEnumerable<T> 是一个泛型接口,用于表示可以被枚举的集合。它定义了用于遍历集合中元素的方法和属性。IEnumerable<T> 是 IEnumerable 的泛型版本,提供了类型安全的枚举功能。 当我们实…

人工智能的可解释性:从黑箱到透明

✨个人主页欢迎您的访问 ✨期待您的三连 ✨ ✨个人主页欢迎您的访问 ✨期待您的三连 ✨ ✨个人主页欢迎您的访问 ✨期待您的三连✨ ​​ ​ 人工智能&#xff08;AI&#xff09;的快速发展和广泛应用&#xff0c;带来了许多革新的成果&#xff0c;但也引发了对其透明性和可解释…

【商城的功能开发】

商城的功能开发是一个复杂且多方面的过程&#xff0c;涉及前端和后端的开发、用户界面设计、数据库管理、支付系统集成等多个环节。以下是一些关键功能和步骤&#xff0c;可以帮助你了解商城开发的基本流程&#xff1a; 一、需求分析 目标用户&#xff1a;确定目标市场和用户需…

基于RNN模型的心脏病预测(tensorflow实现)

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 前言 RNN是很经典的模型&#xff0c;原理参考&#xff1a;深度学习基础–一文搞懂RNN这个案例是一个基础案例&#xff0c;用RNN模型去做一个二分类问题&…

【软考网工笔记】计算机基础理论与安全——网络安全

病毒 Melissa 宏病毒 1. 是一种快速传播的能够感染那些使用MS Word 97 和MS Office 2000 的计算机宏病毒。 2. 前面有**Macro** 表示这是宏病毒&#xff1b; 3. 宏病毒可以感染后缀为.xls的文件&#xff1b;Worm 蠕虫病毒 1. 通常是通过网络或者系统漏洞进行传播。 2. 利用信…

民宿酒店预订系统小程序+uniapp全开源+搭建教程

一.介绍 一.系统介绍 基于ThinkPHPuniappuView开发的多门店民宿酒店预订管理系统&#xff0c;快速部署属于自己民宿酒店的预订小程序&#xff0c;包含预订、退房、WIFI连接、吐槽、周边信息等功能。提供全部无加密源代码&#xff0c;支持私有化部署。 二.搭建环境 系统环境…

leecode718.最长重复子数组

二维空间版 class Solution { public:int findLength(vector<int>& nums1, vector<int>& nums2) {int mnums1.size(),nnums2.size();vector<vector<int>> dp(m,vector<int>(n));int result0;for(int i0;i<m;i)if(nums1[i]nums2[0]){…

【iOS Swift Moya 最新请求网络框架封装通用】

【iOS Swift Moya 最新请求网络框架封装通用】 前言框架结构1.API定义&#xff08;TargetType&#xff09;2. 配置MoyaProvider3. 网络管理器4. 使用示例注意事项进一步优化 前言 设计一个基于Moya的网络请求框架&#xff0c;可以提供灵活的网络请求管理&#xff0c;例如设置请…