96SEO 2026-02-19 21:10 4
。

今天#xff0c;我们结合“给文件排序”这样一个具体的例子#xff0c;来详细讲一讲策略模式的设计意图和应用场景。
除此之外我们主要介绍了策略模式的原理和实现以及如何利用策略模式来移除
分支判断逻辑。
今天我们结合“给文件排序”这样一个具体的例子来详细讲一讲策略模式的设计意图和应用场景。
除此之外在今天的讲解中我还会通过一步一步地分析、重构给你展示一个设计模式是如何“创造”出来的。
通过今天的学习你会发现设计原则和思想其实比设计模式更加普适和重要掌握了代码的设计原则和思想我们甚至可以自己创造出来新的设计模式。
假设有这样一个需求希望写一个小程序实现对一个文件进行排序的功能。
文件中只包含整型数并且相邻的数字通过逗号来区隔。
如果由你来编写这样一个小程序你会如何来实现呢你可以把它当作面试题先自己思考一下再来看我下面的讲解。
你可能会说这不是很简单嘛只需要将文件中的内容读取出来并且通过逗号分割成一个一个的数字放到内存数组中然后编写某种排序算法比如快排或者直接使用编程语言提供的排序函数对数组进行排序最后再将数组中的数据写入文件就可以了。
大小我们没办法一次性加载文件中的所有数据到内存中这个时候我们就要利用外部排序算法具体怎么做可以参看我的另一个专栏《数据结构与算法之美》中的“排序”相关章节了。
多核的优势可以在外部排序的基础之上进行优化加入多线程并发排序的功能这就有点类似“单机版”的
大小即便是单机多线程排序这也算很慢了。
这个时候我们可以使用真正的
解决思路讲完了不难理解。
接下来我们看一下如何将解决思路翻译成代码实现。
我先用最简单直接的方式实现将它实现出来。
具体代码我贴在下面了你可以先看一下。
因为我们是在讲设计模式不是讲算法所以在下面的代码实现中我只给出了跟设计模式相关的骨架代码并没有给出每种排序算法的具体代码实现。
感兴趣的话你可以自行实现一下。
100GB)concurrentExternalSort(filePath);}
~)mapreduceSort(filePath);}}private
Sorter();sorter.sortFile(args[0]);}
}在“编码规范”那一部分我们讲过函数的行数不能过多最好不要超过一屏的大小。
所以为了避免
如果只是开发一个简单的工具那上面的代码实现就足够了。
毕竟代码不多后续修改、扩展的需求也不多怎么写都不会导致代码不可维护。
但是如果我们是在开发一个大型项目排序文件只是其中的一个功能模块那我们就要在代码设计、代码质量上下点儿功夫了。
只有每个小的功能模块都写好整个项目的代码才能不差。
在刚刚的代码中我们并没有给出每种排序算法的代码实现。
实际上如果自己实现一下的话你会发现每种排序算法的实现逻辑都比较复杂代码行数都比较多。
所有排序算法的代码实现都堆在
一个类中这就会导致这个类的代码很多。
而在“编码规范”那一部分中我们也讲到一个类的代码太多也会影响到可读性、可维护性。
除此之外所有的排序算法都设计成
只要掌握了我们之前讲过的设计原则和思想针对上面的问题即便我们想不到该用什么设计模式来重构也应该能知道该如何解决那就是将
类中的某些代码拆分出来独立成职责更加单一的小类。
实际上拆分是应对类或者函数代码过多、应对代码复杂性的一个常用手段。
按照这个解决思路我们对代码进行重构。
重构之后的代码如下所示
MapReduceSort();}sortAlg.sort(filePath);}
}经过拆分之后每个类的代码都不会太多每个类的逻辑都不会太复杂代码的可读性、可维护性提高了。
除此之外我们将排序算法设计成独立的类跟具体的业务逻辑代码中的
那部分逻辑解耦也让排序算法能够复用。
这一步实际上就是策略模式的第一步也就是将策略的定义分离出来。
实际上上面的代码还可以继续优化。
每种排序类都是无状态的我们没必要在每次使用的时候都重新创建一个新的对象。
所以我们可以使用工厂模式对对象的创建进行封装。
按照这个思路我们对代码进行重构。
重构之后的代码如下所示
QuickSort());algs.put(ExternalSort,
ExternalSort());algs.put(ConcurrentExternalSort,
ConcurrentExternalSort());algs.put(MapReduceSort,
SortAlgFactory.getSortAlg(QuickSort);}
SortAlgFactory.getSortAlg(ExternalSort);}
SortAlgFactory.getSortAlg(ConcurrentExternalSort);}
SortAlgFactory.getSortAlg(MapReduceSort);}sortAlg.sort(filePath);}
}经过上面两次重构之后现在的代码实际上已经符合策略模式的代码结构了。
我们通过策略模式将策略的定义、创建、使用解耦让每一部分都不至于太复杂。
不过Sorter
分支判断移除掉那也是有办法的。
我直接给出代码你一看就能明白。
实际上这也是基于查表法来解决的其中的“algs”就是“表”。
SortAlgFactory.getSortAlg(QuickSort)));algs.add(new
SortAlgFactory.getSortAlg(ExternalSort)));algs.add(new
SortAlgFactory.getSortAlg(ConcurrentExternalSort)));algs.add(new
SortAlgFactory.getSortAlg(MapReduceSort)));}public
algRange.getAlg();break;}}sortAlg.sort(filePath);}private
}现在的代码实现就更加优美了。
我们把可变的部分隔离到了策略工厂类和
类中的静态代码段中。
当要添加一个新的排序算法时我们只需要修改策略工厂类和
类中的静态代码段其他代码都不需要修改这样就将代码改动最小化、集中化了。
你可能会说即便这样当我们添加新的排序算法的时候还是需要修改代码并不完全符合开闭原则。
有什么办法让我们完全满足开闭原则呢
语言来说我们可以通过反射来避免对策略工厂类的修改。
具体是这么做的我们通过一个配置文件或者自定义的
标注的策略类然后通过反射了动态地加载这些策略类、创建策略对象当我们新添加一个策略的时候只需要将这个新添加的策略类添加到配置文件或者用
标注即可。
还记得上一节课的课堂讨论题吗我们也可以用这种方法来解决。
来说我们可以通过同样的方法来避免修改。
我们通过将文件大小区间和算法之间的对应关系放到配置文件中。
当添加新的排序算法时我们只需要改动配置文件即可不需要改动代码。
好了今天的内容到此就讲完了。
我们一块来总结回顾一下你需要重点掌握的内容。
分支判断逻辑。
实际上这种认识是很片面的。
策略模式主要的作用还是解耦策略的定义、创建和使用控制代码的复杂度让每个部分都不至于过于复杂、代码量过多。
除此之外对于复杂代码来说策略模式还能让其满足开闭原则添加新策略的时候最小化、集中化代码改动减少引入
实际上设计原则和思想比设计模式更加普适和重要。
掌握了代码的设计原则和思想我们能更清楚的了解为什么要用某种设计模式就能更恰到好处地应用设计模式。
在过去的项目开发中你有没有用过策略模式都是为了解决什么问题才使用的你可以说一说在什么情况下我们才有必要去掉代码中的
作为专业的SEO优化服务提供商,我们致力于通过科学、系统的搜索引擎优化策略,帮助企业在百度、Google等搜索引擎中获得更高的排名和流量。我们的服务涵盖网站结构优化、内容优化、技术SEO和链接建设等多个维度。
| 服务项目 | 基础套餐 | 标准套餐 | 高级定制 |
|---|---|---|---|
| 关键词优化数量 | 10-20个核心词 | 30-50个核心词+长尾词 | 80-150个全方位覆盖 |
| 内容优化 | 基础页面优化 | 全站内容优化+每月5篇原创 | 个性化内容策略+每月15篇原创 |
| 技术SEO | 基本技术检查 | 全面技术优化+移动适配 | 深度技术重构+性能优化 |
| 外链建设 | 每月5-10条 | 每月20-30条高质量外链 | 每月50+条多渠道外链 |
| 数据报告 | 月度基础报告 | 双周详细报告+分析 | 每周深度报告+策略调整 |
| 效果保障 | 3-6个月见效 | 2-4个月见效 | 1-3个月快速见效 |
我们的SEO优化服务遵循科学严谨的流程,确保每一步都基于数据分析和行业最佳实践:
全面检测网站技术问题、内容质量、竞争对手情况,制定个性化优化方案。
基于用户搜索意图和商业目标,制定全面的关键词矩阵和布局策略。
解决网站技术问题,优化网站结构,提升页面速度和移动端体验。
创作高质量原创内容,优化现有页面,建立内容更新机制。
获取高质量外部链接,建立品牌在线影响力,提升网站权威度。
持续监控排名、流量和转化数据,根据效果调整优化策略。
基于我们服务的客户数据统计,平均优化效果如下:
我们坚信,真正的SEO优化不仅仅是追求排名,而是通过提供优质内容、优化用户体验、建立网站权威,最终实现可持续的业务增长。我们的目标是与客户建立长期合作关系,共同成长。
Demand feedback