从零开始单排学设计模式「策略模式」黑铁ii

gdjk gdjk     2023-03-09     676

关键词:


阅读本文大概需要 1.7 分钟。

 

本篇是设计模式系列的第三篇,虽然之前也写过相应的文章,但是因为种种原因后来断掉了,而且发现之前写的内容也很渣,不够系统。所以现在打算重写,加上距离现在也有一段时间了,也算是自己的一个回顾吧!

 

学而时习之,不亦说乎。

 

推荐阅读:

从零开始单排学设计模式「UML类图」定级赛

从零开始单排学设计模式「简单工厂设计模式」黑铁III

 

目前段位:黑铁 II

 

技术图片

 

Let‘s Go!

 

前言

 

设计模式不是语法,是一种巧妙的写法,能把程序变的更加灵活。架构模式比设计模式大,架构模式是战略,而设计模式是战术。

 

设计模式分为3大类型:创建型,行为型,结构型,总共有23种。

 

策略模式

 

策略模式是对算法的包装,是把使用算法的责任和算法本身分割开来,委派给不同的对象管理。策略模式通常把一个系列的算法包装到一系列的策略类里面,作为一个抽象策略类的子类。

 

用一句话来说,就是:“准备一组算法,并将每一个算法封装起来,使得它们可以互换”。

 

在策略模式(Strategy Pattern)中,一个类的行为或其算法可以在运行时更改。这种类型的设计模式属于行为型模式。

 

设计原则有很多,这里直说策略模式中使用到的,参看实例思考哪些地方有用到下面的设计模式: 
1. 封装变化(找出应用中可能需要变化之处,把它们独立出来,不要和哪些不需要变化的代码混在一起。) 
2. 针对接口,超类编程,而不是针对实现编程。 
3. 多用组合,少用继承。

 

业务需求

 

如果让你设计一个商场收银软件,营业员根据客户所购买商品的单价和数量,向客户收费。

 

代码实现

 

看到需求的你,对它进行了一个分析,只需要把数量乘以单价就可以得出总费用了,这可难不倒我,然后写出了最初版本。

 

技术图片

 

很简单,直接声明方法然后就计算出结算的总价了。

 

当你准备提交代码的时候,万恶的产品找到你,给出了一个新版的需求。(暗地里画个圈圈咒诅产品...)

 

新的业务需求

 

如果让你设计一个商场收银软件,营业员根据客户所购买商品的单价和数量,向客户收费。就是现在商场需要搞活动,会给顾客购买的商品进行打折,比如七五折,九五折等等。

 

代码实现

 

这不是计算完总价格之后,在后面乘以一下折扣就可以了。

 

经过改版,新的代码如下:

 

技术图片

技术图片

 

还没有等你进行测试,产品就又找上门来了,我们可能后面会实现满300送100、满200送50....等等的很多活动,所以你程序需要设计灵活一点哈,不然到时候我的需求可以还会有变动的。

 

看到这里,没办法,还是得继续完善程序了,想偷个懒都没有办法,思考这种种得可能,你找寻这有没有能完美贴切这种需求得处理方法。

 

打一折和打九折只是形式的不同,抽象分析出来,所有的打折算法都是一样的,所以打折算法应该是一个类。冥思苦想下,你又写出了第三版程序:

 

这里抽离出来一个现金收费类,现金收取类的抽象方法,收取现金,参数为原价,返回当前价。

技术图片

 

正常收费子类,正常收费,原价返回。

技术图片

 

打折收费子类

技术图片

 

返利收费子类

技术图片

 

CashContext类,通过构造方法,传入具体的收费策略。

技术图片

客户端主要代码

技术图片

 

运行结果

技术图片

 

现在就再也不怕了,如果再增加新的功能,只需要创建新的子类即可。

 

策略模式UML类图

 

技术图片

 

总结

 

意图:定义一系列的算法,把它们一个个封装起来, 并且使它们可相互替换。

 

主要解决:在有多种算法相似的情况下,使用 if...else 所带来的复杂和难以维护。

 

何时使用:一个系统有许多许多类,而区分它们的只是他们直接的行为。

 

如何解决:将这些算法封装成一个一个的类,任意地替换。

 

关键代码:实现同一个接口。

 

应用实例:

1、诸葛亮的锦囊妙计,每一个锦囊就是一个策略。

2、旅行的出游方式,选择骑自行车、坐汽车,每一种旅行方式都是一个策略。

3、JAVA AWT 中的 LayoutManager。

 

优点:

1、算法可以自由切换。

2、避免使用多重条件判断。

3、扩展性良好。

 

缺点:

1、策略类会增多。

2、所有策略类都需要对外暴露。

 

使用场景:

1、如果在一个系统里面有许多类,它们之间的区别仅在于它们的行为,那么使用策略模式可以动态地让一个对象在许多行为中选择一种行为。

2、一个系统需要动态地在几种算法中选择一种。

3、如果一个对象有很多的行为,如果不用恰当的模式,这些行为就只好使用多重的条件选择语句来实现。

 

注意事项:如果一个系统的策略多于四个,就需要考虑使用混合模式,解决策略类膨胀的问题。

 

 

 

往期精彩回顾

Bing挂了!百度又“赢了”

房东:你敢申报,我就涨房租!京东取消年终奖

自己不付出努力的话,就别指望别人帮你了

向高手进阶,从0开始手写实现一个RPC框架

上班划水神器:一个可以在控制台玩斗地主的项目

请不要尝试简化这些代码

首例"FQ"被罚!广东警方对“FQ”上网者重罚

一千行MySQL详细学习笔记(值得学习与收藏)

七点建议助您写出优雅的Java代码

在Java中如何优雅地判空

Java爬取并下载酷狗TOP500歌曲

程序员们,别再学习框架了

专科程序员与本科程序员之间有什么区别

程序员的一天是怎样过的?

技术图片

欢迎关注我的公众号「程序员的成长之路」,阅读更多精彩!




从零开始学习java设计模式|行为型模式篇:策略模式(代码片段)

在本讲,我们来学习一下行为型模式里面的第二个设计模式,即策略模式。概述先看下面的图片,我们去旅游选择出行方式能有很多种,可以骑自行车、可以坐汽车、可以坐火车、可以坐飞机。作为一个程序猿... 查看详情

《从零开始学swift》学习笔记(day68)——cocoatouch设计模式及应用之响应者链与触摸事件

原创文章,欢迎转载。转载请注明:关东升的博客  应用与用户进行交互,依赖于各种各样的事件。事件响应者对象是可以响应事件并对其进行处理的对象,响应者链是由一系列链接在一起的响应者组成的。响应者链在事... 查看详情

kotlin从零单排之小tips(代码片段)

文章目录objectabstractinternalobjectobjectxxx funtest() //todo 这种类型的kotlin类是一种单例模式,在转成java字节码的时候,会变成如下:publicfinalclassxxx publicstaticfinalxxxINSTANCE; privatexxx() publicfinalvo 查看详情

从零开始学微服务06.微服务架构的建设思路

大家好,欢迎来到万猫学社,跟我一起学,你也能成为微服务专家。微服务看起来很美,但其实是需要一个技术体系或平台体系来支撑并且落地的。微服务架构建设分为两种思路:框架模式服务网格(Servic... 查看详情

前端也要学系列:设计模式之策略模式(代码片段)

做前端开发已经好几年了,对设计模式一直没有深入学习总结过。随着架构相关的工作越来越多,越来越能感觉到设计模式成为了我前进道路上的一个阻碍。所以从今天开始深入学习和总结经典的设计模式以及面向对象的几大原... 查看详情

从零开始:机器学习20161101

今天开始学习机器学习,主要在于几个方面,就是机器学习对于我个人的几个方面提升都特别大。不管是金融还是图像。在金融我需要机器学习对于我的策略进行重构与评价。在图像,我擅长的是模式识别,需要大量的数据处理... 查看详情

kotlin从零单排之小tips(代码片段)

文章目录objectabstractinternalobjectobjectxxx funtest() //todo 这种类型的kotlin类是一种单例模式,在转成java字节码的时候,会变成如下:publicfinalclassxxx publicstaticfinalxxxINSTANCE; privatexxx() publicfinalvoidtest() //todo 所以这是一种”... 查看详情

从零开始学多线程之构建快(代码片段)

前文回顾上一篇博客从零开始学多线程之组合对象(三)主要讲解了:1.设计线程安全的类要考虑的因素.2. 对于非线程安全的对象,我们可以考虑使用锁+实例限制(Java监视器模式)的方式,安全的访问它们.3.扩展线程安全类的四种方... 查看详情

从零开始blazorserver--基于策略的权限验证

写这个的原因现在BootstrapBlazor处于大更新时期,Menu组件要改为泛型模式。本来我们的这一篇应该是把Layout改了,但是改Layout肯定要涉及到菜单,如果现在写了呢,就进入一个发布就过时的状态,就很尴尬,所以后面的就稍微拖... 查看详情

从零开始学架构架构知识领域

更新说明本篇文章已经整理完很长时间,总感觉有些不足,因此一直没法,希望润色后再发,深感自己水平有限,迟迟没有动笔。但是收到多位朋友的邀约,思考再三决定逐步完成本系列文章。其中不足,请批评指正,我们一起... 查看详情

从零开始学微服务06.微服务架构的建设思路

大家好,欢迎来到万猫学社,跟我一起学,你也能成为微服务专家。微服务看起来很美,但其实是需要一个技术体系或平台体系来支撑并且落地的。微服务架构建设分为两种思路:框架模式服务网格(Servic... 查看详情

springboot从零单排------初级入门篇

  有人说SSM已死,未来是SpringBoot和SpringCloud的天下,这个观点可能有点极端,但不可否认的是已经越来越多的公司开始使用SpringBoot。所以我将平时学习SpringBoot的内容做个记录,查漏补缺吧 1、创建SpringBoot项目可以通过官... 查看详情

编程学习之简单工厂模式与策略模式

很久之前在学习c++的时候就听到老师说写代码要考虑重构,架构,在此期间学习到了一种简单工厂模式。何为简单工厂模式呢?简单工厂模式又叫静态工厂方法模式(StaticFactoryMethodPattern),是通过专门定义一个类来负责创... 查看详情

《javascript设计模式与开发实践》学习之使用策略模式计算奖金

简洁的做法如下: 查看详情

重学设计模式(三设计模式-策略模式)(代码片段)

1、策略模式  策略,指计策或谋略,是可以实现目标的方案集合。在我们日常生活中其实这种问题也比较常见,比如我们使用地图搜索目的地,在地图上给我们提供了多种路线方案供我们选择。这里的路线方案... 查看详情

从零开始学习java设计模式|结构型模式篇:代理模式

从本讲开始,我们就进入到第三章内容的学习中了,而第三章内容讲的就是结构型模式,所以我们有必要知道什么是结构型模式。什么是结构型模式呢?结构型模式描述如何将类或对象按某种布局组成更大的结构&... 查看详情

android从零单排系列六《android视图控件——textview》(代码片段)

目录前言一.TextView基本介绍二.TextView常用属性介绍三.Activity中设置Textview属性四.Demo示例前言小伙伴们,在上文中我们重点介绍了Android视图控件的基本属性,从本文开始我们就开始将Android中比较常用的一些控件一一盘点... 查看详情

从零开始学习java设计模式|创建型模式篇:单例设计模式(代码片段)

从本讲开始,咱们就要开始正式学习23种设计模式了。当然,我们得按照顺序来学,首先先来学习23种设计模式里面的第一类模式,即创建型模式。创建型模式的主要关注点是"怎样创建对象?",它的... 查看详情