一、前言
在这里直言不讳,这篇博文是看了某位老师新出的一段Java SE视频中的一道作业题,题目很简单,要求用策略模式实现排序;其中有三个字段,需要对这个三个字段(ID,NAME,AGE)进行排序,并且还要求有升序和降序的方式。对此有兴趣的朋友可以在网上搜索获取,在此不做任何说明,避免7+7的厄运。
也许是因为无聊吧,我做了这道简单不能再简单的题目。但是却给了我全新的思考感受,
使我能够更有明确目的地在使用设计模式。
上面加粗的一句话貌似不好理解,太抽象,但又没有比这更能涵盖我所表达的意思了。换句话来说就是又增加了一条使用设计模式的心里暗示,即更有针对性地使用设计模式来解决应用场景中出现的问题。
我用一个更容易理解的比喻来解释一下:应用场景好比是一道菜,设计模式就好比是做这道菜所用的调料,用设计模式解决应用场景的问题也就好比是不同调料搭配起来会让这道菜具有不同的口味。由此引发的一个官方言论,即不要过分依赖设计模式,就好比是盐放的太多了,心里就该咒骂“打死卖盐的”了。
二、寻找应用场景中隐藏的问题
首先让我们来分析一下这道题目,题目要求很明确,就是排序。单拿这道题目作为应用场景,该应用场景中需要对三个字段进行排序;注意应用场景中的问题出现了
1.不仅仅实现排序功能,并且还要实现升序和降序的排序方式,详细点地说就意味着要实现3*2个排序算法。
2.应用场景中的三个字段在未来或许还会增加,并伴随着需要进行排序的可能性,也就是那个“3”会变化。
3.应用场景中的排序方式也是会变化的,即使这个假设放在这个应用场景中不太合适,但是也能说明一些问题的,问题本质上没太大的区别。
4.前三条是针对实现来说地,下面的几条针对可维护性层面来说。我之所以写出这篇博文,是因为我终于思考出设计模式对今后代码的维护也是有很大好处的。为什么说是“终于”?以往看过很多设计模式相关的书籍,里面也曾提到可维护性之类的话题;但是看了之后,也是能够理解,在解决实际问题的时候这些话题可就不翼而飞了,脑海里面只想着我要使用设计模式,而不是我该怎样使用设计模式。我在一番思考之后,对此类话题就很敏感了,换句话来说,选择使用哪种设计模式之前,又多了一条思考路径(前言也提到了这个话题)。
5.结合上述4条,用第五条明确指出代码维护带来的问题。就本文的应用场景,它要实现3*2个排序算法,也就是说以后要维护6个算法;如果两个乘数都在不断的增长,那就要维护N*N个算法。为此需要用更优雅的方式来设计,解决今后对代码维护引发的超大工作量问题。
三、三种设计方案
针对这个应用场景,我脑海里浮现出了三种设计方案。前两种方案是在没太理解策略模式之前经常用到的。后一种设计方案,看上去跟第二个很类似,但是却比前者更具内涵。下面是三种方案的方案以伪代码的方式介绍,就不放代码介绍了,一太占篇幅(好吧,我那是懒!),二此文最后提供第三种解决方案的源码。
本文只阐述我思考后的成果,请勿沉浸在问题和代码表面上!
1.不使用模式
if (升序) {
if (升序比较ID) {
// 比较后的算法
} else if (升序比较NAME) {
// 比较后的算法
} else if (升序比较AGE) {
// 比较后的算法
}
} else if (降序) {
if (降序比较ID) {
// 比较后的算法
} else if (降序比较NAME) {
// 比较后的算法
} else if (降序比较AGE) {
// 比较后的算法
}
}
这个设计可谓很老很糟糕,也算个懒人专用方式(好吧,我承认经常这么干,前提要保证这个需求是千年不变的)。这个设计需要维护6个算法,如果连把比较算法封成一个方法都不弄的话,那就会更悲剧了。请参见第二节第五条里的说明。
2.不完整的策略模式
鉴于上面那个悠久而又古老的设计,再来进一步的优化。
//(1)定义6个实现自Comparator接口的排序算法实现类,有3个针对字段升序排序, 另外3个针对字段降序排序。
//(2)调用Collection.sort(List,Comparator)方法针对List进行排序。
实现Comparator接口也是在使用策略模式,具体参见本文最后的源码附件,同时引发的问题请参见第二节第五条里的说明。
这个设计方式看上去靠谱了很多,但是需要维护的算法(类)还是N*N。
3.比较完整的策略模式
那就继续优化,下面的三步思路足以说明,具体参见本文最后的源码附件。
//(1)定义1个排序方式接口(策略接口)。针对本文所引用的应用场景,该接口提供两个方法,分别对Integer和String类型字段做比较操作;该方法返回的是int类型。
//(2)定义2个实现自先前定义的排序方式接口的实现类(具体策略),分别针对于正序和降序实现各自的算法。因该算法内部使用JDK提供的比较方法,其内部采用的是减法操作,故接口中的两个方法需返回int类型。
//(3)定义3个实现自Comparator接口的排序算法实现类(环境),分别针对三个字段的排序。每个类都分别保有先前定义的排序方式接口的引用,并且实现的方法中需调用该接口引用所提供的相应方法。
特别要注意本节用阿拉伯数字表明的地方。这个设计与第二个设计同样也定义了6个算法类,表面上看是差不多的;不过这里使用了两次策略模式,使维护的算法(类)变为N+N。
4.结论
首先让我们来假设一下:现在需求有变化了,客户方又突然想增加100个字段,并且这新增的字段都需要提供可排序功能;第一种设计暂且不考虑,那就考虑后两种。针对这个新需求,两者的差别慢慢地浮现出来。
请仔细看,第二种设计方式中的每个字段都需要有对应的且类似的2个类,并且应对这样的需求显然愈发无力了,因为维护数量是以乘积计算的;而第三种设计方案,连用了两个策略模式,其中一个是将排序方式和待排序的字段分离开来,使二者的变化不会互相影响对方,使代码维护量变为加法计算,明显比前者达到的效果要好得多。
这时客户方那边又提出了一个新需求,这次不是再加100个字段了,而仅仅是再要增加1个排序方式,如果换成第二种设计方案,是不是要抓狂了?
此番思考之后,得出了这样一个结论:使用抽象的东西要尽可能得将其转换成实际的东西;理解一个实际的东西要尽可能得将其转换成抽象的东西。
四、总结
本文的题目其实有些迷惑性,是说策略模式呢?还是在说思考呢?其实由策略模式引发的思考,不仅是对策略这个单个模式的思考,也是对整个设计模式的全面思考;现阶段的思考重心完全倾向于怎么更给力的使用,绝对的要有目的性的去用;还不会用?有了目的就很好办了,把这个模式的UML图找出来,再把场景问题往里套,就完全OK了。不过说实话,本文还是侧重于对思考后的阐述。
有些幽默的是本文所引发的这个思考是我在不经意间摸索出来的,不过看起来还是很靠谱的,又为我提供了一个思考的路径(不思考永远不会有不经意)。
因本文完全是我思考后的文字,也就是说是用我的思维方式来描述思考的过程,不见得您能读的明白;别着急,只要理解大致意思,用您的思维方式来理解就好了。看书也是同样的道理,用自己的思维方式去理解书中的内容,而不要一味地随着作者的思维方式;换句话说思维方式可以借鉴,但不要模仿。
思考需从不同的角度无限延伸,定能有所收获。
分享到:
相关推荐
后端同学在开发过程中,势必会遇到多条件判断的情况,大部分时候都会直接采用if-else的形式去处理,这样的操作会存在不易扩展的问题,那么...对比枚举策略与简单工厂+策略模式的不同使用,抛砖引玉,引发你更多的思考
在这个案例中,教师改变了传统的教学模式,不再只是灌输知识,而是鼓励学生独立思考,提出质疑,培养他们的批判性思维和问题意识。 在美术鉴赏课堂上,教师通过展示齐白石的《荷花影》引导学生进行感悟式鉴赏。这种...
通过构建详尽的目标消费者画像,包括消费者的需求、行为模式和情感反应,品牌可以更加精准地定位其市场策略。这种细致的用户分析,有助于品牌策略与目标受众的需求和期望相一致,确保品牌信息的传播更具针对性和有效...
《由时代广场工程参与投标报价引发的思考》 在当今快速发展的建筑行业中,投标报价的策略和方式对于企业的生存和发展至关重要。这篇文档通过分析“时代广场”机电工程投标过程,揭示了国内建筑市场与国际惯例之间的...
在探讨幼儿园自主性区域游戏中幼儿深度学习的引发与思考时,首先要理解自主性区域游戏的基本概念。自主性区域游戏强调幼儿在游戏中应保持其自主性,即游戏内容、规则和材料的设定应尽可能由幼儿自行决定,这既体现了...
这一模式的提出,源于对高等教育大众化、教育市场化的深入思考,以及对钱学森之问和李约瑟难题的回应。 1. **提出背景** - **高等教育大众化**:随着适龄人口的减少,高等教育机构面临市场竞争加剧,教育观念也随...
《基于核心素养下的深度学习——由“认识负数”一课引发的思考》一文,以小学六年级的“认识负数”课程为例,深入探讨了如何在教学中实施深度学习策略,使学生在理解和应用数学概念中形成初步的数学思想。...
在《突出过程探索 促进深度学习——由一道模拟题讲评引发的思考.pdf》一文中,作者深入分析了通过一道综合性的数学模拟题,讲述如何在试题讲评中通过突出问题解决的过程来促进学生的深度学习。文章提出了一个...
大数据技术的应用,不仅改变了企业的运营模式,而且对企业市场营销策略的实施带来了重大影响。 首先,大数据技术在市场调研方面带来了革新。传统市场调研需要花费大量时间和资源,而且结果可能存在偏差,数据的可信...
因此,对大学语文教学模式的改革势在必行,需要创新教学策略,以培养学生的创新思维和实践能力。 首先,问题情境式教学是一种有效的教学模式。它要求教师善于运用问题来引导学生进行深入的学习与思考。在这种模式下...
针对这些问题,可以采取以下应对策略: 1. 提升硬件设施和技术支持:政府和学校应投资改善网络环境,提供必要的设备支持,确保每个学生都能顺利参与线上学习。对于经济困难的学生,可以设立援助基金或与企业合作,...
【规制策略】面对AIGC引发的产业革命,新闻传媒业需要审慎应对,既要充分利用AIGC带来的生产赋能,又要防止过度依赖和技术滥用。一方面,政策制定者应当建立健全AIGC的法律框架,设定透明的算法准则,防止误导信息的...
【高中英语词汇教学策略思考】 英语词汇教学是高中英语教育的核心环节,因为它构成了语言学习的基础。没有足够的词汇量,学生将难以理解英语文本,更别提流利地听、说、读、写了。然而,当前的高中英语词汇教学面临...
标题“由‘差评’引发的深度思考.zip”提示我们,这个文件可能包含了对IT产品或服务收到负面评价后的分析和反思。虽然没有具体的标签,我们可以从这个主题推测,内容可能涉及客户服务、产品改进、用户体验设计以及...
首先,教师语言运用是引发幼儿深度学习的重要手段。教师通过有效的课堂语言引导,可以激发幼儿的思维和兴趣,满足幼儿对知识的深度理解需求。具体策略包括: 1. 课堂语言引思维:教师应以引导孩子发现和解决问题的...
《由ChatGPT引发的数字化思考...总的来说,ChatGPT的兴起引发了关于数字化转型的新思考,而e运维作为行业参与者,正积极拥抱新技术,通过创新业务模式和服务方式,应对行业挑战,致力于打造可持续发展的数字化未来。
全国小学数学“深度学习”研究联盟首届研讨会的课例引发了对如何实现深度学习深入探究的思考。 首先,深度学习并不只是简单地让学生掌握更多的知识,而是强调在理解、应用和创新层面上的深化。它要求学生不仅能记住...
在实践上,修正模式建议教师通过创设问题情境,引发学生对既有观念的质疑,同时提供清晰易懂的新概念,让学生在探究活动中亲身经历,从而逐步改变原有的相异构想。 综上所述,小学科学教学应关注学生的个体差异,...