策略模式实现搜索功能

概念:

策略模式是一种行为设计模式,用于定义一系列算法,将他们封装起来,并使他们可以互相替换。使用策略模式可以让代码更加灵活,且易于扩展和维护

背景:

假设你有一个功能需要多种不同的算法或行为实现(如不同的排序方式、不同的支付方式、不同的搜索方式等),这些行为是相似的。但是在细节上有所不同。

核心:

将这些可变的行为封装为不同的策略累,并定义一个接口来规范这些策略的实现。这样就可以在运行时动态切换策略,而不需要修改客户端的代码

用途:

1、替换不同的算法:可以根据需要动态的选择不同的算法或实现。比如不同的折扣策略,不同的支付方式

2、简化条件语句:用策略模式可以替换大量的if-else语句

3、提高可扩展性:新增一种行为时,只需要添加一个新的策略类,而不需要修改现有的代码

基本结构:

1、策略接口(Strategy Interface):定义所有策略类必须实现的方法。

2、具体策略类(Concrete Strategy):每个类实现具体的算法或行为。

3、上下文类(Context):持有一个策略对象并调用策略的方法。

示例:

假设你有一个电商平台,根据用户的等级(普通用户、会员、VIP)给予不同的折扣。我们可以使用策略模式来实现不同的折扣逻辑。

1、定义策略接口

// 策略接口,定义计算折扣的方法
public interface IDiscountStrategy
{decimal CalculateDiscount(decimal price);
}

2、实现具体的策略类

// 普通用户的折扣策略:无折扣
public class NoDiscountStrategy : IDiscountStrategy
{public decimal CalculateDiscount(decimal price){return price; // 无折扣}
}// 会员的折扣策略:10% 折扣
public class MemberDiscountStrategy : IDiscountStrategy
{public decimal CalculateDiscount(decimal price){return price * 0.9m; // 10% 折扣}
}// VIP 的折扣策略:20% 折扣
public class VIPDiscountStrategy : IDiscountStrategy
{public decimal CalculateDiscount(decimal price){return price * 0.8m; // 20% 折扣}
}

3、创建上下文

// 上下文类,用于选择和执行策略
public class ShoppingCart
{private IDiscountStrategy _discountStrategy;// 通过构造函数设置策略public ShoppingCart(IDiscountStrategy discountStrategy){_discountStrategy = discountStrategy;}// 计算折扣后的价格public decimal CalculateTotalPrice(decimal price){return _discountStrategy.CalculateDiscount(price);}
}

4、使用策略模式

public class Program
{public static void Main(string[] args){decimal originalPrice = 100m; // 商品的原价// 普通用户IDiscountStrategy noDiscount = new NoDiscountStrategy();ShoppingCart cartForNormalUser = new ShoppingCart(noDiscount);Console.WriteLine($"普通用户的价格: {cartForNormalUser.CalculateTotalPrice(originalPrice)}");// 会员用户IDiscountStrategy memberDiscount = new MemberDiscountStrategy();ShoppingCart cartForMember = new ShoppingCart(memberDiscount);Console.WriteLine($"会员用户的价格: {cartForMember.CalculateTotalPrice(originalPrice)}");// VIP 用户IDiscountStrategy vipDiscount = new VIPDiscountStrategy();ShoppingCart cartForVIP = new ShoppingCart(vipDiscount);Console.WriteLine($"VIP 用户的价格: {cartForVIP.CalculateTotalPrice(originalPrice)}");}
}

运行结果:

普通用户的价格: 100
会员用户的价格: 90
VIP 用户的价格: 80

理解了策略模式后,开始设计搜索功能。

1、定义策略接口

        public interface ISearchStrategy{List<PatientData> ExecuteSearch();}

2、实现具体的策略类,由于搜索条件有可能同时满足,所以定义组合策略类

    /// <summary>/// 日期搜索/// </summary>public class DateSearchStrategy : ISearchStrategy{private DateTime _date1, _date2;public DateSearchStrategy(DateTime date1, DateTime date2){_date1 = date1.Date;_date2 = date2.Date;}public List<PatientData> ExecuteSearch(){return T_PatientDataAccess.GetPatientArchives(startDate:_date1,endDate: _date2);}}/// <summary>/// 病人姓名搜索/// </summary>public class PatientNameSearchStrategy : ISearchStrategy{private string _name;public PatientNameSearchStrategy(string name){_name = name;}public List<PatientData> ExecuteSearch(){return T_PatientDataAccess.GetPatientArchives(patientName:_name);}}/// <summary>/// 医生姓名搜索/// </summary>public class DoctorNameSearchStrategy : ISearchStrategy{private string _name;public DoctorNameSearchStrategy(string name){_name = name;}public List<PatientData> ExecuteSearch(){return T_PatientDataAccess.GetPatientArchives(patientName: _name);}}/// <summary>/// 组合搜索/// </summary>public class CompositeSearchStrategy : ISearchStrategy{private readonly List<ISearchStrategy> _strategies = new List<ISearchStrategy>();public void AddStrategy(ISearchStrategy strategy){_strategies.Add(strategy);}public List<PatientData> ExecuteSearch(){List<PatientData> datas = new List<PatientData>();// 如果没有条件,返回所有数据if (_strategies.Count == 0){return datas;}// 逐步过滤数据foreach (var strategy in _strategies){if (datas.Count == 0){datas = strategy.ExecuteSearch();     //第一条搜索}else{datas = datas.Where(p1 => strategy.ExecuteSearch().Any(p2 => p1.inspectNumber == p2.inspectNumber)).ToList();   //求交集}}return datas;}

3、定义上下文

public class B_T_patientSearchService{/// <summary>/// 搜索服务/// </summary>/// <param name="startDate">开始日期</param>/// <param name="endDate">结束日期</param>/// <param name="patientName">病人名字</param>/// <param name="doctorName">医生姓名</param>/// <returns></returns>public List<PatientData> Search(string startDate, string endDate, string patientName, string doctorName){var searchStrategy = new CompositeSearchStrategy();if (!string.IsNullOrWhiteSpace(startDate) && !string.IsNullOrWhiteSpace(endDate)){ searchStrategy.AddStrategy(new DateSearchStrategy(DateTime.Parse(startDate),DateTime.Parse(endDate)));}if (!string.IsNullOrWhiteSpace(patientName)){searchStrategy.AddStrategy(new PatientNameSearchStrategy(patientName));}if (!string.IsNullOrWhiteSpace(doctorName)){searchStrategy.AddStrategy(new DoctorNameSearchStrategy(doctorName));}// 传入所有数据,依次应用过滤策略return searchStrategy.ExecuteSearch();}}

4、狠狠的使用它

        /// <summary>/// 搜索功能实现/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void btnSearch_Click(object sender, EventArgs e){PerformSearch(tbStartDate.Text, tbEndDate.Text, cbPatientName.Text, cbDoctorName.Text);ControlStatus(false);}/// <summary>/// 执行查询并绑定数据/// </summary>/// <param name="startDate">开始日期</param>/// <param name="endDate">结束日期</param>/// <param name="patientName">患者姓名</param>/// <param name="doctorName">医生姓名</param>private void PerformSearch(string startDate, string endDate, string patientName, string doctorName){var searchService = new B_T_patientSearchService();var list = searchService.Search(startDate, endDate, patientName, doctorName);DataTable dataTable = new DataTable();if (list != null && list.Count > 0){dataTable = ConvertToDataTable(list);tempTable = dataTable; dataGridView1.AutoGenerateColumns = false;     // 固定标题栏dataGridView1.DataSource = tempTable;// 绑定数据LoadT_PatientArchivesManageToText();}else{dataGridView1.DataSource = dataTable;}lblTotal.Text = "查询总数:" + dataGridView1.RowCount;}

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

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

相关文章

Obsidian git sync error / Obsidian git 同步失敗

Issue: commit due to empty commit message Solution 添加commit資訊&#xff0c;確保不留空白 我的設置&#xff1a;auto-backup: {{hostname}}/{{date}}/

Scala尾递归解决爆栈问题

引言 我在上篇中详细的讲了递归的一系列问题&#xff0c;多路递归&#xff0c;爆栈问题&#xff0c;尾递归优化等&#xff0c;今天就实际演示一下尾递归是如何解决爆栈问题的&#xff0c;以及它的原理是什么&#xff1f; 支持尾递归优化的语言 尾递归是一种特殊的递归形式,如果…

SpringBoot开发——整合Logbook进行HTTP API请求响应日志输出

文章目录 1. 简介依赖管理2. 实战案例2.1 基本用法2.2 结合Logback日志记录到文件2.3 自定义核心类Logbook2.4 自定义日志输出Sink2.5 与RestTemplate集成1. 简介 记录HTTP API请求响应日志对于监控、调试和性能优化至关重要。它帮助开发者追踪API的使用情况,包括请求来源、参…

接口自动化测试推荐用什么框架?

在推荐接口自动化测试框架时&#xff0c;需要考虑多个因素&#xff0c;包括项目需求、技术栈、团队经验和个人偏好。 以下是几个常用的接口自动化测试框架供你参考&#xff1a; Postman&#xff1a; Postman是一个功能强大且易于上手的接口测试工具&#xff0c;它提供了许多…

景联文科技:专业数据标注公司,推动AI技术革新

数据标注作为AI技术发展的重要支撑&#xff0c;对于训练高质量的机器学习模型以及推动应用领域的创新具有不可替代的作用。 景联文科技作为专业的数据标注公司&#xff0c;致力于提供专业的数据标注服务&#xff0c;帮助客户解决AI链条中的数据处理难题&#xff0c;共同推动人工…

Node.js学习记录(二)

目录 一、express 1、初识express 2、安装express 3、创建并启动web服务器 4、监听 GET&POST 请求、响应内容给客户端 5、获取URL中携带的查询参数 6、获取URL中动态参数 7、静态资源托管 二、工具nodemon 三、express路由 1、express中路由 2、路由的匹配 3、…

k8s的加密配置secret和应用配置configmap

目录 加密配置 secret的三种类型 创建opaque类型的两种方式 方法一 方法二 如何把secret挂载到pod当中 把secret作为环境变量传到pod当中 指定harbor私有仓库加密的secret配置 应用配置 configmap 创建configmap的方式 在pod里面用configmap做pod的环境变量 **用c…

Java项目: 基于SpringBoot+mybatis+maven校园资料分享平台(含源码+数据库+答辩PPT+毕业论文)

一、项目简介 本项目是一套基于SpringBootmybatismaven校园资料分享平台 包含&#xff1a;项目源码、数据库脚本等&#xff0c;该项目附带全部源码可作为毕设使用。 项目都经过严格调试&#xff0c;eclipse或者idea 确保可以运行&#xff01; 该系统功能完善、界面美观、操作简…

gdb 前端:kdbg 安装使用

文章目录 1. 前言2. kdbg 安装使用2.1 安装 kdbg2.2 使用 kdbg 1. 前言 限于作者能力水平&#xff0c;本文可能存在谬误&#xff0c;因此而给读者带来的损失&#xff0c;作者不做任何承诺。 2. kdbg 安装使用 2.1 安装 kdbg kdbg 是 gdb 的图形化界面的前端&#xff0c;在 …

如何使用Jmeter关联influxDB?

一、添加"添加后端监听器" 二、后端监听器实现选择&#xff0c;"org. apache. jmeter. visualizers. backend. influxdb.InfluxdbBackendlistenerClient" 三、修改"influxdbUrl&#xff1a;自己的主机、application:取一个项目名" 四、influxDB&…

网络层协议介绍

目录 一、网络层的功能 二、ip数据包格式 三、ICMP协议&#xff08;Internet控制报文协议&#xff09; 3.1功能 3.2 ping命令 3.2.1ping命令的用法 3.2.2扩展 3.3 tracert命令&#xff08;windows&#xff09; 四、arp协议 4.1ARP协议是如何工作的 4.2工作原理&#x…

可提示 3D 分割研究里程碑!SAM2Point:SAM2加持泛化任意3D场景、任意提示!

郑重声明&#xff1a;本解读已获得论文作者的原创解读授权 文章链接&#xff1a;https://arxiv.org/pdf/2408.16768 在线demo: https://huggingface.co/spaces/ZiyuG/SAM2Point code链接&#xff1a;https://github.com/ZiyuGuo99/SAM2Point 亮点直击 无投影 3D 分割&#xff1…

5G毫米波阵列天线仿真——CDF计算(手动AC远场)

之前写过两个关于阵列天线获取CDF的方法&#xff0c;一个通过Realized Gain&#xff0c;一个通过Power Flow&#xff0c; 三个案例中都是3D中直接波束扫描&#xff0c;并没有展示场路结合的情况。这期我们用Power Flow的方法&#xff0c;手动合并AC任务的波束计算CDF。 还是用…

SpringBoot的Web拦截器

拦截器与Filter的区别 首先拦截器(Intercepter)和过滤器&#xff08;Filter&#xff09;都是Web项目中针对Request请求的处理组件&#xff0c;在请求到达业务处理逻辑前&#xff0c;进行预处理&#xff0c;包括监控、安全相关的职责。 所处位置 首先SpringBoot的拦截器本质是…

Nature Communications 可远程操控食欲的口服软体机器人

肥胖对人群的的影响是深远的&#xff0c;它不仅关系到个人的健康&#xff0c;还与全球公共卫生挑战密切相关。据世界卫生组织的数据&#xff0c;全球每8人中就有1人患有肥胖症。肥胖增加了患2型糖尿病、心血管疾病、某些癌症等多种健康问题的风险&#xff0c;并对社会经济产生重…

flink中disableChaining() 的详解

disableChaining() 是 Apache Flink 中用于控制算子链&#xff08;operator chaining&#xff09;行为的一个方法。算子链是 Flink 的一种优化技术&#xff0c;默认情况下会将多个连续的算子合并为一个任务&#xff08;task&#xff09;以减少开销。但在某些情况下&#xff0c;…

【北京迅为】《STM32MP157开发板使用手册》-第十八章 Debian文件系统

iTOP-STM32MP157开发板采用ST推出的双核cortex-A7单核cortex-M4异构处理器&#xff0c;既可用Linux、又可以用于STM32单片机开发。开发板采用核心板底板结构&#xff0c;主频650M、1G内存、8G存储&#xff0c;核心板采用工业级板对板连接器&#xff0c;高可靠&#xff0c;牢固耐…

OpenCV结构分析与形状描述符(20)计算一个包围给定点集的最小外接圆函数minEnclosingCircle()的使用

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 找到一个包围二维点集的最小面积的圆。 该函数使用迭代算法来寻找一个二维点集的最小外接圆。这意味着函数将会通过反复逼近的过程来计算出能够…

ls -l 查看文件信息

​​​​​​​lrwxrwxrwx -&#xff1a;普通文件&#xff08;regular file&#xff09;&#xff0c;例如文本文件、二进制文件等。 例子&#xff1a;-rw-r--r-- 表示一个普通文件&#xff0c;具有读写权限。 d&#xff1a;目录&#xff08;directory&#xff09;。 例子&…

【Go】-基于Gin和GORM的小清单项目

目录 项目介绍 简介 技术 项目结构 项目分析 总结 项目介绍 简介 项目地址&#xff1a;knoci/list: 基于Gin的待办清单小项目 (github.com) 一个仿照github/Q1mi/bubble 做的一个gin框架练习 技术 gin 框架gorm 操作PostgreSQLini 配置文件 项目结构 list ├── R…