设计模式—策略模式

目录

一、定义

二、特点

三、优点

四、缺点

五、实例

六.涉及到的知识点

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定义了一系列的可供重用的算法或行为。继承有助于析取出这些算法中的公共功能
  • 简化了单元测试,因为每个算法都有自己的类,可以通过自己的接口单独测试
  • 每个算法可以保证他没有错误,修改其中任一个时也不会影响其他的算法、
  • 当不同的行为堆砌在一个类中时,可以在使用这些行为的类中消除条件语句
  • 策略模式就是用来封装算法的,但在实践中,我们发现可以用它来封装几乎任何类型的规则,只要在分析过程中听到需要在不同时间应用不同的业务规则,就可以考虑使用策略模式处理这种变化的可能性

四、缺点

  1. 策略模式造成很多的策略类,增加维护难度。
  • 客户端必须理解所有策略算法的区别,以便适时选择恰当的算法类


五、实例

做一个商场收银软件,根据选择的收费方式(正常收费、打五折、打八折……)去计算客户所花的钱数(单价、数量)

现金收费抽象类

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、六大关系

六大关系


七、思维导图

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

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

相关文章

新的雅思口语6分标准

目录 新的雅思口语6分标准 要有细节&#xff0c;要有充分的话题词汇资源 要拥有具象思维能力&#xff0c;要有画面感 下义词是什么意思&#xff1f; 方法&#xff1a;现在时未来时 &#xff08;形成时态多样&#xff09;观点解释 原因要有排他性 "Kick off" 是…

windows系统服务器在不解锁屏幕不输入密码的前提下,电脑通电开机启动程序。

在控制面板中找到“管理工具”中的 “任务计划程序”&#xff0c;打开“任务计划程序”窗口。如图&#xff1a; 双击打开任务计划程序&#xff0c;空白出右键创建基本任务&#xff0c;或者点击最右侧的创建基本任务。 输入名称&#xff0c;点击下一步。 先选择计算机启动时&a…

开启智能时代:深度解析智能文档分析技术的前沿与应用

开启智能时代&#xff1a;深度解析智能文档分析技术的前沿与应用 本章主要介绍文档分析技术的理论知识&#xff0c;包括背景介绍、算法分类和对应思路。通过本文学习&#xff0c;你可以掌握&#xff1a;1. 版面分析的分类和典型思想 2. 表格识别的分类和典型思想 3. 信息提取的…

JavaScript 手写题

基础手写 全排列&#xff08;力扣原题&#xff09; 要求以数组的形式返回字符串参数的所有排列组合。 注意&#xff1a; 字符串参数中的字符无重复且仅包含小写字母返回的排列组合数组不区分顺序const _permute string > {const result []const map new Map()const df…

百万级并发IM即时消息系统(3)配置数据初始化和前后端交互

04_配置数据初始化及前后端交互_哔哩哔哩_bilibili 1.配置文件 创建一个config文件夹以及一个app.yaml配置文件。 该文件专门存放一些关键配置&#xff0c;如mysql DNS路径和redis的addr账号密码等。 后期可以创建一个工具包和一些初始化方法&#xff0c;专门用来加载这些配…

用AI + Milvus Cloud搭建着装搭配推荐系统教程

以下函数定义了如何将图像转换为向量并插入到 Milvus Cloud 向量数据库中。代码会循环遍历所有图像。(注意:如果需要开启 Milvus Cloud 全新特性动态 Schema,需要修改代码。) 查询向量数据库 以下代码演示了如何使用输入图像查询 Milvus Cloud 向量数据库,以检索和上传…

学习 使用pandas库 DataFrame 使用

1 、 数据排序 sort_values()函数 by:要排序的名称或名称列表&#xff0c; sorted_df df.sort_values(byAge,ascendingFalse) 由大到小排序&#xff1b; sorted_df df.sort_values(byAge) 由小到大排序&#xff1b; # 创建一个示例数据帧 data {Name: [Tom, Nick, John…

spring:事务失效+事务传播行为

一、事务失效 1.Transactional作用在非public上 Transactionalvoid transferAccounts(){adminDao.sub();System.out.println(10/0);adminDao.add();} 只执行sub&#xff08;&#xff09; 2.异常被try catch捕获 Transactionalpublic void transferAccounts(){adminDao.sub(…

C语言每日一练---Day(14)

本专栏为c语言练习专栏&#xff0c;适合刚刚学完c语言的初学者。本专栏每天会不定时更新&#xff0c;通过每天练习&#xff0c;进一步对c语言的重难点知识进行更深入的学习。 今日练习题关键字&#xff1a;统计每个月兔子的总数 数列的和 &#x1f493;博主csdn个人主页&#x…

【分布式技术专题】「OSS中间件系列」Minio的文件服务的存储模型及整合Java客户端访问的实战指南

Minio的元数据 数据存储 MinIO对象存储系统没有元数据数据库&#xff0c;所有的操作都是对象级别的粒度的&#xff0c;这种做法的优势是: 个别对象的失效&#xff0c;不会溢出为更大级别的系统失效。便于实现"强一致性"这个特性。此特性对于机器学习与大数据处理非…

vue3+ts+uniapp小程序端自定义日期选择器基于内置组件picker-view + 扩展组件 Popup 实现自定义日期选择及其他单列选择

vue3ts 基于内置组件picker-view 扩展组件 Popup 实现自定义日期选择及单列选择 vue3tsuniapp小程序端自定义日期选择器 1.先上效果图2.代码展示2.1 组件2.2 公共方法处理日期2.3 使用组件(全局自动导入的情况) 3.注意事项3.1refSelectDialog3.1 backgroundColor"#fff&q…

DP读书:鲲鹏处理器 架构与编程(十一)鲲鹏生态软件架构 AND 硬件特定软件

鲲鹏生态软硬件构成 鲲鹏软件构成硬件特定软件1. Boot Loader2. SBSA 与 SBBR3. UEFI4. ACPI 鲲鹏软件构成 鲲鹏处理器的软件生态是一个不断发展的软件生态&#xff0c;服务器本身也具有复杂度多样性&#xff0c;经过很长时间的发展服务器硬件有不同的操作系统方案&#xff0c…

pdfh5在线预览pdf文件

前言 pc浏览器和ios的浏览器都可以直接在线显示pdf文件&#xff0c;但是android浏览器不能在线预览pdf文件&#xff0c;如何预览pdf文件&#xff1f; Github: https://github.com/gjTool/pdfh5 Gitee: https://gitee.com/gjTool/pdfh5 使用pdfh5预览pdf 编写预览页面 <…

开源电子合同签署平台小程序源码 在线签署电子合同小程序源码 合同在线签署源码

聚合市场上各类电子合同解决方案商&#xff0c;你无需一个一个的对接电子合同厂商&#xff0c;费时&#xff0c;费力&#xff0c;因为这个工作我们已经做了适配&#xff0c;你只需要一个接口就能使用我们的所有服务商&#xff0c;同时你还可以享受我们的接口渠道价格。 Mini-C…

Python飞机大战小游戏

游戏规则&#xff1a;键盘上下左右键控制飞机移动 游戏展示图片&#xff1a; 源码&#xff1a; 第一个py命名为&#xff1a;plane_main.py import pygamefrom plane_sprites import *class PlaneGame(object):# """飞机大战主游戏"""def __in…

解决Jackson解析JSON时出现的Illegal Character错误

&#x1f337;&#x1f341; 博主猫头虎 带您 Go to New World.✨&#x1f341; &#x1f984; 博客首页——猫头虎的博客&#x1f390; &#x1f433;《面试题大全专栏》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33a; &a…

【Seata】00 - Seata Server 部署(Windows、Docker 基于 Jpom)

文章目录 前言参考目录版本说明Windows 部署 seata-server1&#xff1a;下载压缩包2&#xff1a;文件存储模式3&#xff1a;db 存储模式3.1&#xff1a;建表3.2&#xff1a;修改配置文件3.3&#xff1a;启动脚本4&#xff1a;源码部署 Docker 部署 seata-server &#xff08;基…

Spring与MyBatis集成 AOP整合PageHelper插件

目录 1.什么是集成&#xff1f; 2.Spring与MyBatis集成 3.Spring与MyBatis集成的基本配置 4.AOP整合PageHelper插件 1.什么是集成&#xff1f; 集成是指将不同的组件、框架或系统整合到一起&#xff0c;使它们可以协同工作、相互调用、共享资源等。通过集成&#xff0c;可以…

金鼎奖正式揭晓!创邻科技荣获“优秀技术创新奖”

近期&#xff0c;由中国人民银行直属企业中国金融电子化集团有限公司主办的2023中国国际金融展“金鼎奖” 评选结果正式对外公布&#xff01;创邻科技凭借在数据库领域的技术创新和产品引领荣获“优秀技术创新奖”。 作为中国国际金融展的重要活动之一&#xff0c;今年的 “金鼎…

【MTK平台】根据kernel log分析wifi scan的时候流程

一 概要: 本文主要讲解根据kernel log分析下 当前路径下(vendor/mediatek/kernel_modules/connectivity/wlan/core/gen4m/)wifi scan的时候代码流程 二. Log分析: 先看Log: 2.1)在Framework层WifiManager.java 方法中,做了一个标记,可以精准的确认时间 这段log可以…