【精选】设计模式——策略设计模式-两种举例说明,具体代码实现

Java策略设计模式

在这里插入图片描述

简介

策略设计模式是一种行为型设计模式,它允许在运行时选择算法的行为。

在软件开发中,我们常常需要根据不同情况采取不同的行为。通常的做法是使用大量的条件语句来实现这种灵活性,但这会导致代码变得复杂、难以维护和扩展。

策略设计模式通过将每种行为封装到一个独立的类中,并使它们可以相互替换,从而避免了大量的条件判断语句。

在这里插入图片描述

示例

假设我们正在开发一个电商平台,需要计算订单的折扣金额。根据不同的用户类型,有不同的折扣策略。

首先,我们定义一个抽象策略类DiscountStrategy,它包含一个抽象方法calculateDiscount用于计算折扣金额。

public abstract class DiscountStrategy {public abstract double calculateDiscount(double price);
}

然后,我们创建具体的策略类:RegularCustomerDiscount(普通用户折扣策略)和VIPCustomerDiscount(VIP用户折扣策略)。它们分别继承自DiscountStrategy并实现了calculateDiscount方法。

public class RegularCustomerDiscount extends DiscountStrategy {@Overridepublic double calculateDiscount(double price) {// 普通用户折扣计算逻辑return price * 0.9;}
}public class VIPCustomerDiscount extends DiscountStrategy {@Overridepublic double calculateDiscount(double price) {// VIP用户折扣计算逻辑return price * 0.8;}
}

最后,我们创建一个上下文类Order,它包含一个策略对象,并提供一个方法calculateFinalPrice用于计算订单的最终价格。

public class Order {private DiscountStrategy discountStrategy;public void setDiscountStrategy(DiscountStrategy discountStrategy) {this.discountStrategy = discountStrategy;}public double calculateFinalPrice(double price) {return discountStrategy.calculateDiscount(price);}
}

现在,我们可以使用策略模式来计算不同用户类型的订单折扣金额,而无需修改订单类的代码。

public class Main {public static void main(String[] args) {Order order = new Order();// 普通用户订单DiscountStrategy regularCustomerDiscount = new RegularCustomerDiscount();order.setDiscountStrategy(regularCustomerDiscount);double regularCustomerPrice = order.calculateFinalPrice(100);System.out.println("普通用户价格:" + regularCustomerPrice);// VIP用户订单DiscountStrategy vipCustomerDiscount = new VIPCustomerDiscount();order.setDiscountStrategy(vipCustomerDiscount);double vipCustomerPrice = order.calculateFinalPrice(100);System.out.println("VIP用户价格:" + vipCustomerPrice);}
}

输出结果:

普通用户价格:90.0
VIP用户价格:80.0

例子二:
让我们以一个商场销售促销活动的场景为例进行代码实现。

假设在商场中有多种促销活动,如打折、满减和赠品活动。根据顾客的购买情况和优惠条件,商场需要动态选择不同的促销策略来给顾客提供最优惠的价格。

首先,我们定义一个抽象的促销策略接口 PromotionStrategy

public interface PromotionStrategy {double applyDiscount(double price);
}

然后,我们创建具体的促销策略类,分别实现打折、满减和赠品活动的算法:

public class DiscountPromotion implements PromotionStrategy {private double discountRate;public DiscountPromotion(double discountRate) {this.discountRate = discountRate;}@Overridepublic double applyDiscount(double price) {return price * (1 - discountRate);}
}public class FullReductionPromotion implements PromotionStrategy {private double fullAmount;private double reductionAmount;public FullReductionPromotion(double fullAmount, double reductionAmount) {this.fullAmount = fullAmount;this.reductionAmount = reductionAmount;}@Overridepublic double applyDiscount(double price) {if (price >= fullAmount) {return price - reductionAmount;} else {return price;}}
}public class FreeGiftPromotion implements PromotionStrategy {private String gift;public FreeGiftPromotion(String gift) {this.gift = gift;}@Overridepublic double applyDiscount(double price) {System.out.println("You got a free gift: " + gift);return price;}
}

接下来,我们定义一个商场类 ShoppingMall,其中包含一个促销策略的成员变量,并提供一个设置促销策略的方法:

public class ShoppingMall {private PromotionStrategy promotionStrategy;public void setPromotionStrategy(PromotionStrategy promotionStrategy) {this.promotionStrategy = promotionStrategy;}public double calculatePrice(double price) {if (promotionStrategy != null) {price = promotionStrategy.applyDiscount(price);}return price;}
}

现在我们可以使用这些类进行测试:

public class Main {public static void main(String[] args) {ShoppingMall shoppingMall = new ShoppingMall();// 设置打折促销策略PromotionStrategy discountPromotion = new DiscountPromotion(0.2);shoppingMall.setPromotionStrategy(discountPromotion);double discountedPrice = shoppingMall.calculatePrice(100);System.out.println("Discounted price: " + discountedPrice);// 设置满减促销策略PromotionStrategy fullReductionPromotion = new FullReductionPromotion(200, 50);shoppingMall.setPromotionStrategy(fullReductionPromotion);double reducedPrice = shoppingMall.calculatePrice(300);System.out.println("Reduced price: " + reducedPrice);// 设置赠品促销策略PromotionStrategy freeGiftPromotion = new FreeGiftPromotion("T-shirt");shoppingMall.setPromotionStrategy(freeGiftPromotion);double giftPrice = shoppingMall.calculatePrice(100);System.out.println("Final price: " + giftPrice);}
}

这段代码首先创建了一个商场对象 shoppingMall,然后通过设置不同的促销策略来计算价格。在不同的促销策略下,商场会根据顾客购买的物品和优惠条件动态选择最优惠的价格。

希望这个例子能够帮助你更好地理解策略模式的实际应用!如果你还有其他问题,请随时提问。
通过使用策略设计模式,我们可以轻松地添加新的折扣策略,而无需修改订单类的代码。这样使得代码更加灵活、可扩展和易于维护。

策略模式的优势

在这里插入图片描述

策略设计模式有以下几个优势:

  1. 灵活性:策略模式可以根据需要在运行时选择不同的算法,而不需要修改原有的代码。这使得系统更加灵活,可以根据不同的需求动态地切换和替换算法。

  2. 可扩展性:由于每个算法都被封装到独立的策略类中,因此很容易添加新的策略。只需要创建一个新的策略类并实现相应的算法即可,而不会影响其他代码的稳定性。

  3. 代码复用:策略模式可以将通用的算法逻辑封装到一个抽象策略类中,然后通过继承和实现来扩展具体的策略类。这样可以避免重复编写相同的代码,提高了代码的复用性。

  4. 单一责任原则:策略模式能够将不同的算法逻辑分离开来,使得每个策略类只负责自己的算法实现。这符合单一责任原则,使得代码更加清晰、可读性更强。

策略模式的应用场景

策略设计模式在许多场景中都可以发挥作用。以下是一些常见的应用场景:

  1. 排序算法:不同的排序算法有不同的实现方式,如冒泡排序、快速排序、插入排序等。使用策略模式可以将这些算法封装到独立的策略类中,并在运行时选择合适的算法。

  2. 支付方式:在线购物平台通常支持多种支付方式,如信用卡支付、支付宝、微信支付等。使用策略模式可以将每种支付方式封装到一个独立的策略类中,并根据用户的选择来动态切换支付方式。

  3. 日志记录:不同类型的日志可能需要采用不同的记录方式,如文件记录、数据库记录、网络发送等。使用策略模式可以将不同的记录方式封装到策略类中,根据配置或条件来选择合适的记录方式。

  4. 缓存策略:在开发中,我们经常会使用缓存来提高系统的性能。不同的数据访问模式可能需要采用不同的缓存策略,如先进先出(FIFO)、最近最少使用(LRU)等。通过使用策略模式,我们可以将不同的缓存策略封装到独立的策略类中,并在运行时选择合适的策略。

  5. 图像处理:图像处理涉及许多算法,如调整图像大小、滤镜效果、图像旋转等。使用策略模式可以将不同的图像处理算法封装到独立的策略类中,并根据用户需求选择合适的算法来处理图像。

这些只是策略设计模式的一些常见应用场景,实际上它可以应用于各种需要根据不同条件选择不同行为的情况。通过使用策略模式,我们可以使代码更加灵活、可维护和可扩展,同时降低了代码的复杂度。

希望本文对你理解和应用策略设计模式有所帮助!如果你还有任何问题,请随时提问。

策略模式与其他设计模式的区别

策略模式与其他设计模式有一些相似之处,但也有一些明显的区别。

  1. 策略模式 vs. 工厂模式

    • 工厂模式是一种创建型模式,它将对象的创建逻辑封装到一个工厂类中,客户端通过工厂类来创建对象。而策略模式是一种行为型模式,它将不同的算法封装到独立的策略类中,并在运行时选择合适的策略。
    • 工厂模式主要关注对象的创建,而策略模式主要关注算法的选择和切换。
    • 工厂模式通常用于创建具有相同接口的对象,而策略模式可以用于封装任意类型的算法。
  2. 策略模式 vs. 模板方法模式

    • 模板方法模式是一种行为型模式,它定义了一个算法的骨架,将一些步骤延迟到子类实现。而策略模式则将整个算法封装到独立的策略类中,并在运行时动态选择策略。
    • 模板方法模式强调保持算法骨架的稳定性,而策略模式强调算法的灵活性。
  3. 策略模式 vs. 委托模式

    • 委托模式是一种对象组合模式,它将任务的执行委托给其他对象来完成。而策略模式则是将不同的算法封装到独立的策略类中,并在运行时选择合适的策略。
    • 委托模式侧重于任务的分配和执行,而策略模式侧重于算法的选择和切换。

总的来说,策略模式通过将不同的算法封装到独立的策略类中,使得代码更加灵活、可扩展和可维护。它与工厂模式、模板方法模式和委托模式有一些相似之处,但也有明显的区别。根据具体的需求和场景,我们可以选择适合的设计模式来解决问题。

总结

策略设计模式是一种非常常用且有价值的设计模式,它可以提供灵活、可扩展和可复用的代码结构。通过封装不同的算法到独立的策略类中,策略模式能够简化代码、降低耦合性,并使得系统更加可维护和可扩展。

在实际开发中,我们经常会遇到需要根据不同条件选择不同行为的情况,这时候策略模式就是一个很好的选择。希望本文对你理解和应用策略设计模式有所帮助!

如果你想深入了解策略设计模式,可以参考《Head First 设计模式》一书中关于策略模式的章节,它详细介绍了策略设计模式的原理和实现方式。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/203878.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Unity打包EXE自定义(拖拽)窗口大小

代码 using System.Collections; using System.Collections.Generic; using UnityEngine; using System; using System.Runtime.InteropServices; public class MyWindow : MonoBehaviour {[DllImport("user32.dll")]private static extern IntPtr GetActiveWindow(…

CSS-自适应导航栏(flex | grid)

目标:实现左右各有按钮,中间是内容,自适应显示中间的内容导航栏,即 根据中间的宽度大小显示内容。 自适应导航栏 总结:推荐 flex布局 / grid布局 flex布局: 两侧 flex:1; ----->中间自适应 grid布局&…

uniapp(微信小程序)聊天实例,支持图片,语音,表情(附源码)

效果预览 安装教程 配置 请参考Dome 会话配置 {info:{// 用户关键字userKey:2666,// 用户手机userPhone:15252156614,// 用户昵称userName: 健健,// 头像headImg: http://d.hiphotos.baidu.com/image/h%3D300/sign0defb42225381f3081198ba999004c67/6159252dd42a2834a75bb01…

CRM客户关系管理系统的主要功能有哪些?

我们都知道,CRM系统可以帮助企业加快业务增长。如果一个企业能提高业务效率、跨团队协作、有效管理客户、轻松共享和同步数据,那么企业竞争力将极大地提高。基于此,我们说说CRM客户关系管理系统的主要功能分析。 完整的CRM是什么样的&#x…

红队专题-开源资产扫描系统-ARL资产灯塔系统

ARL资产灯塔系统 安装说明问题 : 安装说明 源码地址 https://github.com/TophantTechnology/ARL https://github.com/TophantTechnology/ARL/wiki/Docker-%E7%8E%AF%E5%A2%83%E5%AE%89%E8%A3%85-ARL 安装环境 uname -a Linux VM-24-12-centos 3.10.0-1160.49.1.e…

亚马逊云科技re:Invent,生成式AI正在彻底改变开发者的工作方式

去年此时,ChatGPT横空出世席卷全球,许多人称其意味着AI的iPhone时刻到来。CSDN创始人蒋涛对此曾预测:「下一步就是应用时刻,新应用时代将来临……大模型将推动更多的AI应用程序员诞生」。 在2023亚马逊云科技re:Invent全球大会第三…

Linux--环境变量

一.基本概念 * 环境变量 (environment variables) 一般是指在操作系统中用来指定操作系统运行环境的一些参数 * 如:我们在编写 C/C 代码的时候,在链接的时候,从来不知道我们的所链接的动态静态库在哪里,但 是照样可以链接成功&am…

使用jenkins插件Allure生成自动化测试报告

前言 以前做自动化测试的时候一直用的HTMLTestRunner来生成测试报告,后来也尝试过用Python的PyH模块自己构建测试报告,在后来看到了RobotFramework的测试报告,感觉之前用的测试报告都太简陋,它才是测试报告应该有的样子。也就是在…

微信小程序 -- ios 底部小黑条样式问题

问题&#xff1a; 如图&#xff0c;ios有的机型底部伪home键会显示在按钮之上&#xff0c;导致点击按钮的时候误触 解决&#xff1a; App.vue <script>export default {wx.getSystemInfo({success: res > {let bottomHeight res.screenHeight - res.safeArea.bott…

c语言五子棋

下面是一个简单的C语言五子棋实现示例&#xff1a; #include <stdio.h>#include <stdlib.h>#define BOARD_SIZE 15char board[BOARD_SIZE][BOARD_SIZE];void init_board() { int i, j; for (i 0; i < BOARD_SIZE; i) { for (j 0; j < BOARD_…

HarmonyOS4.0从零开始的开发教程09页签切换

HarmonyOS&#xff08;七&#xff09;页签切换 List组件和Grid组件的使用 Tabs组件的使用 概述 在我们常用的应用中&#xff0c;经常会有视图内容切换的场景&#xff0c;来展示更加丰富的内容。比如下面这个页面&#xff0c;点击底部的页签的选项&#xff0c;可以实现“首页…

CTF工控工业互联网(ISC)复现总结WP(超详细)

工业互联网复现 Modbus协议&#xff1a;MMS协议&#xff1a;ISC工业互联网比赛题目复现&#xff1a;Modbus协议分析&#xff1a;组态软件安全分析&#xff1a;工业协议分析1&#xff1a;工业协议分析2&#xff1a;特殊的工控流量&#xff1a; Modbus协议&#xff1a; Modbus 市…

JavaScript中的连续赋值问题a.x = a = {n:2}

输出以下代码的执行结果并解释为什么 var a {n: 1}; var b a; a.x a {n: 2}; console.log (a.x); console.log (b.x); 下面来分析下这段简单代码的工作步骤&#xff0c;从而进一步理解js引用类型“赋值”的工作方式。 首先第一行和第二行 var a {n:1}; var b a; …

JVM 命令行监控及诊断工具

面试题 你使用过Java虚拟机性能监控和故障处理工具吗&#xff1f;&#xff08;美图&#xff09; 怎么打出线程栈信息。&#xff08;字节跳动&#xff09; JVM诊断调优工具用过哪些&#xff1f; (京东) 怎么获取 Java 程序使用的内存&#xff1f;堆使用…

学生成绩管理系统(Java)

开发环境: Windows 11 IDEA 2021.3.3 需求: package com.it.neu;import java.util.ArrayList; import java.util.Scanner;import static java.time.Clock.system;class Student { //创建学生类private String Stu_name;private String Stu_id;public Student(String id, S…

圆通单号查询,圆通速递物流查询,对需要的单号进行颜色标记

批量查询圆通速递单号的物流信息&#xff0c;并对需要的单号进行颜色标记。 所需工具&#xff1a; 一个【快递批量查询高手】软件 圆通速递单号若干 操作步骤&#xff1a; 步骤1&#xff1a;运行【快递批量查询高手】软件&#xff0c;第一次使用的伙伴记得先注册&#xff0c…

【Java】实现顺序表基本的操作(数据结构)

文章目录 前言顺序表1、打印顺序表2、增加元素3、在任意位置增加元素4、判断是否包含某个元素5、查找某个元素对于的位置6、获取任意位置的元素7、将任意位置的元素设为value8、删除第一次出现的关键字9、获取顺序表长度10、清空顺序表总结 前言 在了解顺序表之前我们要先了解…

Kubernetes集群安装高可用postgresql

Kubernetes集群安装高可用postgresql Bitnami 提供的 postgresql-ha 解决方案是一个预配置的、高可用的 PostgreSQL 集群配置&#xff0c;通常部署在 Kubernetes 环境中。它使用了一些关键技术和组件来实现数据库的高可用性。&#xff0c;Bitnami postgresql-ha 主要采用以下构…

JVM 虚拟机(二)类的生命周期

类的声明周期描述了一个类加载、使用和卸载的整个过程。 一个类的声明周期包括五个阶段&#xff1a;加载、连接、初始化、使用、卸载&#xff0c;其中连接部分分为验证、准备和解析阶段。 加载阶段 加载阶段是第一步是类加载器根据类的全限定名通过不同的渠道以二进制流的方式…

区块链媒体:Web3.0时代的推广创新10爆款策略概览-华媒舍

随着Web3.0时代的到来&#xff0c;互联网推广正经历着一场创新的革命。在这个新的时代背景下&#xff0c;一系列全新的推广策略正在兴起&#xff0c;引领着市场的变革。本文将基于这一背景&#xff0c;为大家介绍Web3.0时代中的10大爆款推广策略概览。 1. 个性化推广 在Web3.0…