策略模式:封装行为策略,灵活切换实现多态业务逻辑

文章目录

  • 一、引言
  • 二、应用场景
  • 三、模式定义与实现
  • 四、优缺点分析
  • 总结

一、引言

​ 策略模式(Strategy Pattern)是一种行为型设计模式,它定义了算法族,并分别封装起来,让它们之间可以互相替换。这种模式使得算法的变化独立于使用算法的客户端,从而实现多态性的策略选择。

二、应用场景

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

  1. 系统需要在多种算法中进行切换,每种算法解决的是同一类问题,但具体实现和表现不同。
  2. 需要在运行时根据具体情况动态地选择合适的算法来执行。

例如,在电商系统中,针对不同的会员等级可能有不同的折扣计算方式,如普通会员打折、VIP会员折上折、尊享会员满减等。策略模式可以帮助灵活地切换并应用这些不同的折扣策略。

三、模式定义与实现

策略模式的核心组成部分包括:

在这里插入图片描述

  1. Strategy(策略接口/抽象类):声明了一系列方法,用于定义所有支持的算法的公共接口。
  2. ConcreteStrategy(具体策略类):实现了Strategy接口,提供了具体的算法实现。
  3. Context(上下文角色):持有一个Strategy对象引用,用以调用其方法来执行相关算法,并在必要时能够更改所使用的策略。

以电商平台的折扣策略为例,来具体实现策略模式:

  1. 定义策略接口(Strategy):创建一个名为DiscountStrategy的接口,其中包含一个计算折扣的方法。

    public interface DiscountStrategy {
        double calculateDiscount(double originPrice, int memberLevel);
    }
    
  2. 定义具体策略类(ConcreteStrategy):为每种会员等级创建相应的折扣策略实现类,如NormalMemberDiscountVIPMemberDiscountPremiumMemberDiscount

    public class NormalMemberDiscount implements DiscountStrategy {
        @Override
        public double calculateDiscount(double originPrice, int memberLevel) {
            return originPrice * 0.9; // 普通会员9折
        }
    }
    
    public class VIPMemberDiscount implements DiscountStrategy {
        @Override
        public double calculateDiscount(double originPrice, int memberLevel) {
            return originPrice * 0.85; // VIP会员8.5折
        }
    }
    
    public class PremiumMemberDiscount implements DiscountStrategy {
        @Override
        public double calculateDiscount(double originPrice, int memberLevel) {
            if (originPrice > 500) {
                return originPrice - 200; // 尊享会员满500减200
            } else {
                return originPrice * 0.8; // 若不满500元,按8折计算
            }
        }
    }
    
  3. 定义上下文角色(Context):创建一个名为Order的类,其中包含一个DiscountStrategy对象的引用,并提供设置和获取折扣策略的方法,以及计算订单实际价格的方法。

    public class Order {
        private DiscountStrategy discountStrategy;
    
        public void setDiscountStrategy(DiscountStrategy strategy) {
            this.discountStrategy = strategy;
        }
    
        public double calculateFinalPrice(double originPrice, int memberLevel) {
            return discountStrategy.calculateDiscount(originPrice, memberLevel);
        }
    }
    
  4. 应用端使用:在应用程序中,可以根据会员等级动态选择并应用相应的折扣策略。

    public class StrategyPatternDemo {
        public static void main(String[] args) {
            Order order = new Order();
    
            int normalMemberLevel = 1;
            order.setDiscountStrategy(new NormalMemberDiscount());
            System.out.println("普通会员应付金额:" + order.calculateFinalPrice(1000, normalMemberLevel));
    
            int vipMemberLevel = 2;
            order.setDiscountStrategy(new VIPMemberDiscount());
            System.out.println("VIP会员应付金额:" + order.calculateFinalPrice(1000, vipMemberLevel));
    
            int premiumMemberLevel = 3;
            order.setDiscountStrategy(new PremiumMemberDiscount());
            System.out.println("尊享会员应付金额:" + order.calculateFinalPrice(1000, premiumMemberLevel));
        }
    }
    
    

测试结果

在这里插入图片描述

四、优缺点分析

优点:

  1. 提高了系统的灵活性:策略模式允许在运行时动态地改变和选择算法,增强了程序的可扩展性。
  2. 易于新增策略:只需添加新的具体策略类即可增加新的行为,对已有代码无影响。

潜在挑战:

  1. 可能导致类数量增加:每一种策略都需要创建一个新的类,当策略种类较多时,类的数量会迅速增长。
  2. 客户端必须了解各种策略之间的区别:客户端需要知道如何选择和切换策略,这可能会增加客户端的复杂性。

总结

​ 策略模式通过将一系列可互换的算法封装成单独的类,使得客户端可以在运行时动态地选择或更换算法,从而实现灵活多变的行为策略。在实际应用中,合理运用策略模式有助于简化业务逻辑,降低耦合度,提高代码的可维护性和复用性。同时应注意控制策略类的增长,避免过度设计,确保模式的应用符合实际需求。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Linux中数据库sqlite3的基本命令的使用

数据库概念介绍 数据库安装 首先将本地的三个sqlite3安装包移动到共享文件夹然后在移动到自己创建的文件夹中如下: 然后对安装包进行解压如下:sudo dpkg -i *.deb检查是否安装成功sqlite数据库命令 系统命令 , 都以’.开头 .exit .quit .…

My个人网页。

<!DOCTYPE html> <html lang"en"> <head> <meta charset"UTF-8"> <meta name"viewport" content"widthdevice-width, initial-scale1.0"> <title>花花的个人网页</title> <style>bod…

Github 2024-02-25开源项目日报 Top10

根据Github Trendings的统计&#xff0c;今日(2024-02-25统计)共有10个项目上榜。根据开发语言中项目的数量&#xff0c;汇总情况如下&#xff1a; 开发语言项目数量Python项目5Jupyter Notebook项目2TypeScript项目2非开发语言项目1HTML项目1C项目1Dart项目1 Python - 100天…

【OnlyOffice】 桌面应用编辑器,版本8.0已发布,PDF表单、RTL支持、Moodle集成、本地界面主题

ONLYOFFICE桌面编辑器v8.0是一款功能强大、易于使用的办公软件&#xff0c;适用于个人用户、企业团队和教育机构&#xff0c;帮助他们高效地处理文档工作并实现协作。无论是在Windows、macOS还是Linux平台上&#xff0c;ONLYOFFICE都能提供无缝的编辑和共享体验。 目录 ONLYOFF…

Stable Diffusion 模型分享:【Checkpoint】YesMix(动漫、2.5D)

本文收录于《AI绘画从入门到精通》专栏,专栏总目录:点这里。 文章目录 模型介绍生成案例案例一案例二案例三案例四下载地址模型介绍 条目内容类型大模型基础模型SD 1.5来源

完全分布式运行模式

完全分布式运行模式 分析&#xff1a;之前已经配置完成 ​ 1&#xff09;准备3台客户机&#xff08;关闭防火墙、静态ip、主机名称&#xff09; ​ 2&#xff09;安装JDK ​ 3&#xff09;配置环境变量 ​ 4&#xff09;安装Hadoop ​ 5&#xff09;配置环境变量 ​ 6&am…

Qt开发 入门

Qt开发 入门 Qt Hello World程序 使用"按钮”实现 纯代码方式实现 &#xff08;1&#xff09;创建工程 剩下的直接下一步即可 &#xff08;2&#xff09;编写代码&#xff0c;widget.cpp #include "widget.h" #include "ui_widget.h"#include &…

Sui在AIBC Eurasia奖项评选中被评为2024年度最佳区块链解决方案

自2023年主网上线以来&#xff0c;经历了爆炸性增长的Layer1区块链Sui在2月25–27日迪拜举办的第二届AIBC Eurasia活动中获得“2024最佳区块链解决方案奖”&#xff08;Best Real World Application Award 2024&#xff09;。这个盛大的活动以世界级的参与者和往届获奖者而闻名…

MATLAB中的makeweight函数

W makeweight(dcgain,[freq,mag],hfgain) W makeweight(dcgain,[freq,mag],hfgain,Ts) W makeweight(dcgain,[freq,mag],hfgain,Ts,N) W makeweight(dcgain,wc,hfgain,___) W makeweight(dcgain,wc,hfgain&#xff0c;___)表示增益交叉频率wc。该语法相当于将…

华为大数据平台-FusionInsight MRS

1、产品定位 (1) 关于华为的大数据平台&#xff0c;本人之前用过FusionInsight HD版本&#xff0c;近期也在用MRS结合MPP和治理平台做湖仓一体的开发&#xff0c;其实MRS是在HD基础上进行的升级、改版&#xff0c;MRS是集成一些开源的大数据组件&#xff0c;有自己的运维和安全…

【已解决】用ArcGIS处理过的数据在QGIS中打开发生偏移怎么办?| 数据在ArcGIS中打开位置正常,在QGIS中偏移

1. 问题描述 栅格或者矢量数据用ArcGIS打开时位置正确&#xff08;可以和其他数据对应上&#xff09;。但是用QGIS打开后发现位置不对 2. 问题的原因 因为该数据用了ArcGIS自定义的坐标系&#xff0c;QGIS不支持&#xff0c;识别有误。因此在数据QGIS中的坐标系参数有误&a…

4. client-go 编程式交互

Kubernetes 系统使用 client-go 作为 Go 语言的官方编程式交互客户端库&#xff0c;提供对 Kubernetes API Server 服务的交互访问。Kubernetes 的源码中已经集成了 client-go 的源码&#xff0c;无须单独下载。client-go 源码路径为 vendor/k8s.io/client-go。 开发者经常使用…

Mistral发布语言大模型Mistral Large;法国新星Mistral挑战 OpenAI 霸主地位

&#x1f989; AI新闻 &#x1f680; Mistral发布语言大模型Mistral Large 摘要&#xff1a;Mistral Large 是 Mistral AI 公司最新发布的旗舰语言模型&#xff0c;具备顶尖水平的推理能力。它主要被设计用于处理复杂的多语言推理任务&#xff0c;比如文本理解、转换和代码生…

Flink应用场景

1、介绍 (1) Apache Flink 功能强大&#xff0c;支持开发和运行多种不同种类的应用程序。它的主要特性包括&#xff1a;批流一体化、精密的状态管理、事件时间支持以及精确一次的状态一致性保障等。Flink 不仅可以运行在包括 YARN、 Mesos、Kubernetes 在内的多种资源管理框架…

C++:list容器(非原生指针迭代器的实现)

本章是STL容器 list 的模拟实现。 之前已经使用 C语言 对带头双向循环链表 进行实现&#xff0c;详见数据结构: 线性表(带头双向循环链表实现), 相较于之前的实现&#xff0c;C 下多了对迭代器以及模板等相关语法特性。下面将着重讲解这些新知识。 文章目录 一. list 的基本框架…

新火种AI|微软扶持下一个OpenAI?Mistral AI新模型对标GPT-4,上线即挤爆

作者&#xff1a;一号 编辑&#xff1a;美美 OpenAI的大金主微软&#xff0c;还想缔造“下一个OpenAI”。 周一晚间&#xff0c;成立仅9个月的Mistral AI正式发布了最强力的旗舰模型Mistral Large。和此前他们所推出的一系列模型不同&#xff0c;Mistral AI本次发布的版本性…

c语言经典测试题7

1.题1 int main() {int count 0;int x -1;while (x){count;x x >> 1;}printf("%d", count);return 0; } 上述代码的运行结果是什么呢&#xff1f; 我们来分析一下&#xff1a;我们知道在vs中右移操作符的规则是&#xff0c;右边抛弃&#xff0c;左边由符…

什么是智能合约

前言&#xff1a;在介绍智能合约的前提下&#xff0c;需要先介绍一下区块链 一.什么是区块链 区块链实质上是一个去中心化、分布式的可进行交易的数据库或账本&#xff0c;具有下列典型特征&#xff1a; 去中心化&#xff1a;简单来说&#xff0c;在网络上一个或多个服务器瘫…

nn.Linear() 使用提醒

原本以为它是和nn.Conv2d()一样&#xff0c;就看第二个维度的数值&#xff0c;今天才知道&#xff0c;它是只看最后一个维度的数值&#xff01;&#xff01;&#xff01; 例子1 Descripttion: Result: Author: Philo Date: 2024-02-27 14:33:50 LastEditors: Philo LastEditT…

GCN,R-GCN,岭回归,SVR,随机森林,Adaboost

图卷积神经网络(graph convolutional network, GCN),它将卷积神经网络拓展到图结构形式 中&#xff0c;GCN因可以很好地融合图结构数据的结构特征和属性特征并且有较好的组合泛化能力而被广泛使用。 关系图卷积神经网络(relational-graph convolutional network, R-GCN)&#…