设计模式—策略模式
目录
一、定义
二、特点
三、优点
四、缺点
五、实例
六.涉及到的知识点
1、一个类里面有哪些东西?
2、类和实例
什么是类?
什么是实例?
什么是实例化?
3、字段和属性
什么是字段?
属性是什么?
属性怎么用呢?
属性有什么作用?
静态属性是什么?
属性和字段的公有部分解释:
4、修饰符
5、访问修饰符有哪些?
6、this关键字传递的是什么?
this关键字和对象之间有什么关系?
如果省略this会怎么样?
7、构造方法
8、方法重载
9、抽象类
什么是抽象类?
什么是重写?
10、switch....case多分支语句
if-else if与switch的比较
11、六大原则
12、六大关系
七、思维导图
一、定义
它定义了算法家族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化,不会影响到使用算法的客户
商场都有打折、返现活动—“满300减100”、“打五折”、“打八折”,我们可以根据自己花的钱数去选择对应的支付方式,这里的支付方式就可以理解为一种算法,算法本身只是一种策略。这些算法之间都可以相互替换。

二、特点
算法之间可以相互替换;
相同方式调用所有算法;
消除条件语句
三、优点
- 是一种定义一系列算法的方法,从概念上来看,所有这些算法完成的都是相同的工作,只是实现不同,他可以以相同的方式调用所有的算法,减少了各种算法与使用算法类之间的耦合
- 策略模式的Strategy类层次为Context定义了一系列的可供重用的算法或行为。继承有助于析取出这些算法中的公共功能
- 简化了单元测试,因为每个算法都有自己的类,可以通过自己的接口单独测试
- 每个算法可以保证他没有错误,修改其中任一个时也不会影响其他的算法、
- 当不同的行为堆砌在一个类中时,可以在使用这些行为的类中消除条件语句
- 策略模式就是用来封装算法的,但在实践中,我们发现可以用它来封装几乎任何类型的规则,只要在分析过程中听到需要在不同时间应用不同的业务规则,就可以考虑使用策略模式处理这种变化的可能性
四、缺点
- 策略模式造成很多的策略类,增加维护难度。
- 客户端必须理解所有策略算法的区别,以便适时选择恰当的算法类
五、实例
做一个商场收银软件,根据选择的收费方式(正常收费、打五折、打八折……)去计算客户所花的钱数(单价、数量)

现金收费抽象类
abstract class CashSuper
{public abstract double acceptCash(double money);
}
正常收费子类
class CashNormal : CashSuper
{public override double acceptCash(double money) //正常收费,原价返回{return money;}
}
打折收费子类
class CashRebate : CashSuper
{private double moneyRebate = 1d; //私有变量,钱数public CashRebate(string moneyRebate) //构造方法{//ToDo:double.Parse():把括号里面string内容转换为double类型//#中double.TryParse方法和double.Parse方法的异同之处://https://www.cnblogs.com/xu-yi/p/11178601.htmlthis.moneyRebate = double.Parse(moneyRebate); //将钱数字符串转换为双精度类型}public override double acceptCash(double money) //重写抽象方法{return money * moneyRebate;}
}
返利收费子类
class CashReturn : CashSuper
{//返利收费,初始化时必须要输入返利条件和返利值,//比如满200返100,则moneyCondition为300,moneyReturn为100private double moneyCondition = 0.0d; //返利条件private double moneyReturn = 0.0d; //返利值public CashReturn(string moneyCondition, string moneyReturn) //构造方法,传的值转换为double双精度类型{this.moneyCondition = double.Parse(moneyCondition);this.moneyReturn = double.Parse(moneyReturn);}public override double acceptCash(double money) //重写抽象方法{double result = money; //定义一个变量,记录最后总计if (money > moneyCondition) //判断,所花钱数是否>返利条件result = money - Math.Floor(money / moneyCondition) * moneyReturn; //总计=花的钱-(花的钱/返利条件)*返利值return result; //返回最后钱数}
}
现金收费工厂类
class CashFactory
{public static CashSuper createcashAccept(string type){CashSuper cs = null; //现金收费抽象类变量为空switch (type) //根据选择条件返回相应的对象{case "正常收费":cs = new CashNormal(); //实例化正常收费子类break;case "满300返100": CashReturn cr1 = new CashReturn("300", "100"); //实例化返利收费子类cs = cr1; //赋值break;case "打8折":CashRebate cr2 = new CashRebate("0.8"); //实例化打折收费子类cs = cr2; //赋值break; }return cs;}
}
客户端代码
private void button1_Click(object sender, EventArgs e)
{//Combox.SelectedItem:获取下拉框所选中的项//Combox.SelectedIndex:获取下拉框选中项的索引CashSuper csuper = CashFactory.createcashAccept(cbxType.SelectedItem.ToString());totalPrices = csuper.acceptCash(Convert.ToDouble(txtPrice.Text) * Convert.ToDouble(txtNumber.Text));total = total + totalPrices; //总计=上次的总计钱数+最新一次的钱数listBox1.Items.Add("单价:" + txtPrice.Text + " " //下拉框显示清单,通过多态,可以得到收取费用的结果+ "数量:" + txtNumber.Text + " " +"合计:" + totalPrices.ToString());label4.Text = total.ToString(); //label显示钱数
}
六.涉及到的知识点
1、一个类里面有哪些东西?

2、类和实例
什么是类?
就是具有相同的属性和功能的对象的抽象的集合。注意:
- 类名称首字母大写。多个单词则各个首字母大写;
- 对外公开的方法需要用‘public’修饰符。
什么是实例?
就是一个真实的对象。比如我们都是‘人’,而你和我其实就是‘人’类的实例了。
什么是实例化?
创建对象的过程,使用new关键字来创建。
Cat cat = new Cat(); //其实做了两件事情Cat cat; //第一步、声明一个Cat的对象,对象名为cat
cat = new Cat(); //第二步、将此cat对象实例化
3、字段和属性
什么是字段?
是存储类要满足其设计所需要的数据,字段是与类相关的变量。
private string name = ""; //name就是一个字段,私有的类变量
注意:
- 如果在定义字段时,在字段的类型前面使用了readonly关键字,那么字段就为只读字段,它只能在以下两个位置被赋值或者传递到方法中被改变。
- 在定义字段时赋值;
- 在类的构造函数内被赋值,或传递到方法中被改变,而且在构造函数中可以被多次赋值。
属性是什么?
是一个方法或一对方法体。提供对类或对象的访问。
属性怎么用呢?
它有两个方法get和set。
get访问器:从属性获取值。返回与声明的属性相同的数据类型,表示的意思是调用时可以得到内部字段的值或引用;
set访问器:为属性赋值。没有显式设置参数,但它有一个隐式参数,用关键字value表示,它的作用是调用属性时可以给内部的字段或引用赋值。
属性有什么作用?
限制外部类对类中成员的访问权限,定义在类级别上。
private int _age; //年龄
public int Age
{get //也可以直接在属性中进行判断操作、设置限制{if (_age >= 0 && _age <= 150) //如果年龄大于 0并且小于150的,(表示输入正确){return _age; //则返回输入的年龄}else //否则,(表示输入错误){return 18; //返回指定年龄18}}set { _age = value; }
}
静态属性是什么?
在属性前面加static关键字,这个属性就成为了静态属性。
有什么作用呢?
- 不管类是否有实例,它们都是存在的。
- 当从类的外部访问时,必须使用类名引用,而不是实例名。
class Person
{private static string name; //字段public static string Name //属性{get { return name; }set { name = value; }}
}
static void Main(string[] args)
{Person.Name = "小菜"; //不需要实例化Person类即可直接对属性赋值
}
属性和字段的公有部分解释:
内存:
- 字段:分配内存
- 属性:不分配内存
命名规范:
- 字段:Camel大小写
- 属性:Pascal小写
4、修饰符
在变量前面可以加上访问修饰符(readonly、static)

readonly(只读):读取该字段的值不能给字段赋值
static:静态字段,可以直接通过类名访问该字段
5、访问修饰符有哪些?
- public:公有的,对任何类可访问
- private:私有的,只在类的内部可以访问,成员默认是这个
- protected:保护的,只允许该类的派生类访问
- internal:内部的,同一项目所有类可访问

6、this关键字传递的是什么?
- 用于区分类的成员和本地变量或参数;
- 作为调用方法的实参
//this调用成员变量或成员方法
class Person
{private string name; //字段public void setName(string name) //方法{this.name = name; //将参数值赋予类中的成员变量}//成员变量和setName()方法中的形式参数的名称相同,都为name,那么如何区分使用的是哪一个变量呢?//使用this关键字代表本类对象的引用,this.name指Person类中name成员变量,等号后面的name指传过来的形参name
}
this作为方法的返回值
public Book getBook()
{return this; //返回Book类引用
}在getBook()类中,方法的返回值为Book类,所以方法体中使用return this这种形式将Book类的对象返回
this关键字和对象之间有什么关系?
this引用的就是本类的一个对象。
如果省略this会怎么样?
直接写成name=name,只是把形参name赋值给参数变量本身而已,成员变量name的值没有改变
7、构造方法
- 什么时候用?就是对类进行初始化(在创建该类的对象时就会调用)。
- 有哪些特点?与类同名
无返回值
不需要void,在new时候调用
//希望每个小猫一诞生就有姓名
class Cat
{private string name =""; //声明Cat类的私有字符串变量namepublic Cat(string name) //定义Cat类的构造方法,参数是输入一个字符串{this.name =name; //将参数赋值给私有变量name}public string Shout(){return "我的名字叫"+name+" 喵";}
}
注:所有类都有构造方法,如果你不编码则系统默认生成空的构造方法,若有定义的构造方法,那么默认的构造方法就会失效(这个构造方法什么也不做,只是为了让用户能够顺利地实例化)
8、方法重载
是什么?指方法名相同,但参数的数据类型、个数或顺序不同的方法。(一同二不同)
有什么好处?在不改变原方法的基础上,新增功能。
class Animal
{private string name;//方法重载:方法名相同、数据类型、个数/顺序不同public Animal(){} //无参的构造方法public Animal(string name) //有参的构造方法{this.name = name;}
}
9、抽象类
什么是抽象类?
目的:抽取相同代码,实现封装思想
特点:
- 抽象类不能实例化;
- 抽象方法是必须被子类重写的方法;
- 如果类中包含抽象方法,那么类就必须定义为抽象类,不论是否还包含其他一般方法
什么是重写?
将父类实现替换为它自己的实现
| 虚成员 | 抽象成员 | |
| 关键字 | virtual | abstract |
| 实现体 | 有实现体 | 没有实现体,被分号取代 |
| 在派生类中被覆写 | 可重写,也可不重写,使用override | 必须被重写,使用override |
10、switch....case多分支语句

什么时候使用switch语句?
当一个变量可能有多个值时
| switch(表达式) { case 值 1: 语句块 1; break; case 值 2: 语句块 2; break; ... default: 语句块 n; break; } |
说明:
switch语句中表达式的结果必须是int、string、char、bool等数据类型;
如果switch语句中表达式的值与case后面的值相同,则执行相应的case后面的语句块;
case后面的值不能重复;
如果case语句为空,则可以不包含break
if-else if与switch的比较
相同点:都可以实现多分支结构
不同点:if-else if:可以处理范围
switch:一般只能用于等值比较
三者的区别:if有条件的执行一条语句
if-else有条件的执行一条或另一条语句
switch有条件的执行多条语句中的其中一条语句
11、六大原则
六大原则
12、六大关系
六大关系
七、思维导图

相关文章:
设计模式—策略模式
目录 一、定义 二、特点 三、优点 四、缺点 五、实例 六.涉及到的知识点 1、一个类里面有哪些东西? 2、类和实例 什么是类? 什么是实例? 什么是实例化? 3、字段和属性 什么是字段? 属性是什么࿱…...
LPDDR4、DDR4
核心信息: 2400Mbps(每秒传输2400*1百万bit) 2400MT/s(百万次/秒) 信号...
ESP32C3 LuatOS RC522①写入数据并读取M1卡
LuatOS RC522官方示例 官方示例没有针对具体开发板,现以ESP32C3开发板为例。 选用的RC522模块 ESP32C3-CORE开发板 注意ESP32C3的 SPI引脚位置,SPI的id2 示例代码 -- LuaTools需要PROJECT和VERSION这两个信息 PROJECT "helloworld" VERSIO…...
MusicBrainz Picard for Mac :音乐文件ID3编辑器
MusicBrainz Picard for Mac是一款macOS平台的音乐文件ID3编辑器,能够帮助我们在Mac电脑上编辑音乐文件的ID3标签信息,包括艺人、专辑等信息,非常快速和简单方便。Picard是下一代MusicBrainz标记应用程序。 这个新的标签概念是面向专辑的&…...
❤ Uniapp使用
❤ Uniapp使用 一、介绍 uni-app官网:https://uniapp.dcloud.io/api/media/image?idpreviewimage 微信小程序官网:https://developers.weixin.qq.com/miniprogram/dev/api/media/image/wx.previewImage.html 二、使用 1、uniapp 实现图片预览 单图预…...
解密Spring事务生效的内部机制
声明式事务和编程式事务对比: 声明式事务: 使用注解或XML配置的方式,在代码中声明事务的属性和行为。通过AOP和代理模式实现,将事务管理与业务逻辑代码解耦。适用于大多数情况,简化了代码,提高了可维护性和…...
大数据时代下的数据安全防护
随着大数据时代的来临,数据安全防护成为了一个重要的问题。在大数据时代,数据的规模和价值都得到了极大的提升,因此数据安全的重要性也变得越来越突出。本文将从数据加密、访问控制、网络安全和人员管理四个方面来介绍大数据时代下的数据安全…...
RabbitMQ-常用命令
RabbitMQ常用命令 3.1 启动停止rabbitMQ命令 # 前台启动Erlang VM 和 RabbitMQ 当窗口关闭或者ctrlc时,使退出了。 rabbitmq-server# 使用系统命令启动 systemctl start rabbitmq-server# 后台启动 rabbitmq-server -detached# 停止rabbitMQ和Erlang VM rabbitmq-…...
Spring中依赖注入的继承bean的细节问题
介绍 有时我们会对一种类型的bean进行继承,在Spring生成bean的时候,返回类型有时是子类类型,有时会父类类型。那么到底在什么情况下用哪种类型呢?肯定有不少人会忽略这点,本篇文章就是把这个细节讲清楚 案例 父类Ba…...
海外腾讯云服务器手机上无法访问外网怎么办??
本文将介绍腾讯云服务器无法访问外网的一些常见原因以及解决办法,同时解答了手机无法访问腾讯云服务器的问题。 腾讯云服务器(Tencent Cloud Server)是一种基于云计算技术的虚拟服务器,可以满足用户对于计算、存储、网络等方面的需…...
python3+requests:接口自动化测试(二)
前言:上篇文章python3requestsunittest:接口自动化测试(一):已经介绍了基于unittest框架的实现接口自动化,但是也存在一些问题,比如最明显的测试数据和业务没有区分开,接口用例不便于…...
uni-app:允许字符间能自动换行(英文字符、数字等)
<template><view class"container"><!-- 这里是你的文本内容 -->{{ multilineText }}</view> </template><style> .container {word-break: break-all; } </style>例如: <template><view class"…...
day 42 |● 121. 买卖股票的最佳时机 ● 122.买卖股票的最佳时机II
121. 买卖股票的最佳时机 dp数组需要记录两种状态,一种是当天时手中还持有股票,一种是当天时手中已卖出股票。 func maxProfit(prices []int) int {dp : make([][]int, len(prices))dp[0] []int{-prices[0], 0}for i : 1; i < len(prices); i{val0…...
SQLserver基础入门理论(超基础)
♥️作者:小刘在C站 ♥️个人主页: 小刘主页 ♥️努力不一定有回报,但一定会有收获加油!一起努力,共赴美好人生! ♥️学习两年总结出的运维经验,以及思科模拟器全套网络实验教程。专栏…...
(三)行为模式:7、观察者模式(Observer Pattern)(C++示例)
目录 1、观察者模式(Observer Pattern)含义 2、观察者模式的UML图学习 3、观察者模式的应用场景 4、观察者模式的优缺点 (1)优点: (2)缺点 5、C实现观察者模式的实例 1、观察者模式&…...
2019CVPR Semantic Graph Convolutional Networks for 3D Human Pose Regression
基于语义图卷积网络的三维人体姿态回归 源码 https://github.com/garyzhao/SemGCN 摘要 在本文中,我们研究了学习图卷积网络(GCN)回归的问题。GCN的当前体系结构受限于卷积滤波器和共享的变换矩阵为的小感受野。为了解决这些限制ÿ…...
大数据课程K16——Spark的梯度下降法
文章作者邮箱:yugongshiyesina.cn 地址:广东惠州 ▲ 本章节目的 ⚪ 了解Spark的梯度下降法; ⚪ 了解Spark的梯度下降法家族(BGD,SGD,MBGD); ⚪ 掌握Spark的MLlib实现…...
springboot:时间格式化的5种方法(解决后端传给前端的时间格式转换问题)推荐使用第4和第5种!
本文转载自:springboot:时间格式化的5种方法(解决后端传给前端的时间显示不一致)_为什么前端格式化日期了后端还要格式化_洛泞的博客-CSDN博客 时间问题演示 为了方便演示,我写了一个简单 Spring Boot 项目ÿ…...
六、vim编辑器的使用
1、编辑器 (1)编辑器就是一款软件。 (2)作用就是用来编辑文件,譬如编辑文字、编写代码。 (3)Windows中常用的编辑器,有自带的有记事本(notepad),比较好用的notepad、VSCode等。 (4)Linux中常用的编辑器,自带的最古老的vi&…...
【易售小程序项目】项目介绍与系列文章集合
项目介绍 易售二手小程序主要用于校园中二手商品的交易,该系列文章会记录这个小程序前端的整个开发过程并提供详细代码,后台主要基于若依管理系统搭建,文章中也会提及后端关键部分的实现及代码。希望该系列文章可以帮助小白了解项目的开发流…...
wordpress后台更新后 前端没变化的解决方法
使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…...
调用支付宝接口响应40004 SYSTEM_ERROR问题排查
在对接支付宝API的时候,遇到了一些问题,记录一下排查过程。 Body:{"datadigital_fincloud_generalsaas_face_certify_initialize_response":{"msg":"Business Failed","code":"40004","sub_msg…...
Prompt Tuning、P-Tuning、Prefix Tuning的区别
一、Prompt Tuning、P-Tuning、Prefix Tuning的区别 1. Prompt Tuning(提示调优) 核心思想:固定预训练模型参数,仅学习额外的连续提示向量(通常是嵌入层的一部分)。实现方式:在输入文本前添加可训练的连续向量(软提示),模型只更新这些提示参数。优势:参数量少(仅提…...
进程地址空间(比特课总结)
一、进程地址空间 1. 环境变量 1 )⽤户级环境变量与系统级环境变量 全局属性:环境变量具有全局属性,会被⼦进程继承。例如当bash启动⼦进程时,环 境变量会⾃动传递给⼦进程。 本地变量限制:本地变量只在当前进程(ba…...
JavaScript 中的 ES|QL:利用 Apache Arrow 工具
作者:来自 Elastic Jeffrey Rengifo 学习如何将 ES|QL 与 JavaScript 的 Apache Arrow 客户端工具一起使用。 想获得 Elastic 认证吗?了解下一期 Elasticsearch Engineer 培训的时间吧! Elasticsearch 拥有众多新功能,助你为自己…...
【论文笔记】若干矿井粉尘检测算法概述
总的来说,传统机器学习、传统机器学习与深度学习的结合、LSTM等算法所需要的数据集来源于矿井传感器测量的粉尘浓度,通过建立回归模型来预测未来矿井的粉尘浓度。传统机器学习算法性能易受数据中极端值的影响。YOLO等计算机视觉算法所需要的数据集来源于…...
【Web 进阶篇】优雅的接口设计:统一响应、全局异常处理与参数校验
系列回顾: 在上一篇中,我们成功地为应用集成了数据库,并使用 Spring Data JPA 实现了基本的 CRUD API。我们的应用现在能“记忆”数据了!但是,如果你仔细审视那些 API,会发现它们还很“粗糙”:有…...
图表类系列各种样式PPT模版分享
图标图表系列PPT模版,柱状图PPT模版,线状图PPT模版,折线图PPT模版,饼状图PPT模版,雷达图PPT模版,树状图PPT模版 图表类系列各种样式PPT模版分享:图表系列PPT模板https://pan.quark.cn/s/20d40aa…...
CMake控制VS2022项目文件分组
我们可以通过 CMake 控制源文件的组织结构,使它们在 VS 解决方案资源管理器中以“组”(Filter)的形式进行分类展示。 🎯 目标 通过 CMake 脚本将 .cpp、.h 等源文件分组显示在 Visual Studio 2022 的解决方案资源管理器中。 ✅ 支持的方法汇总(共4种) 方法描述是否推荐…...
网站指纹识别
网站指纹识别 网站的最基本组成:服务器(操作系统)、中间件(web容器)、脚本语言、数据厍 为什么要了解这些?举个例子:发现了一个文件读取漏洞,我们需要读/etc/passwd,如…...
