狂言重构 之 职责单一原则真的简单吗

大话重构 之 职责单一原则真的简单吗

(图片显示不完整的小伙伴们刷新下网页)

发散式变化,字面上不好理解,一码给你说的例子。

一个类中有7个方法,要适配到另外一种数据库需要改动其中3个方法,而要新增另外一种金融工具插件需要改动其中4个方法,也就是不同维度的改变,要修改同一个类。

敏感的你,是否想到了啥?对的,该类违反了最基础的 职责单一原则 ,不同维度的改变都要改它。

职责单一原则 如此基础,如此“简单”,已经深入到每个软件开发人员的血液中了,为什么还得说?还得专门说?

一方面是看到很多即使工作多年的小伙伴,也经常神不知鬼不觉地就遭了“职责不单一”的道。

一方面原则这种类似真理/艺术的东西,总让人说不清道不明,究竟能说清楚不?

一方面 职责单一原则 真是一门不断发展的艺术,涉及面太广,想给你唠嗑唠嗑。

一码抛砖引玉,希望引发你更多的交流和思考。

狂言重构 之 职责单一原则真的简单吗

为什么一不小心就会踩到“职责不单一”的雷

即便是经验丰富的程序员写出的程序,也会有违背这一原则的代码存在。为什么呢?因为 职责扩散

所谓 职责扩散 ,就是因为某种原因,本来单一的职责需要被分化成多个职责。

拿个例子来说,统计文章的词频。只统计一篇文章的时候,一句话的事情,一个类就搞定了。但是要统计一个论文库里面所有文章的时候呢?数据量太大,各种大数据处理框架就出来了,一打论文都说不完。一个职责“统计词频”,起码就分成了两个职责“大数据处理”和“统计词频的业务逻辑”。

另外 职责扩散 的初期不容易识别,所以容易写出违反 职责单一原则 的代码。

狂言重构 之 职责单一原则真的简单吗

面向职责单一的设计

对于小范围的代码层面,职责问题可以说是对粒度的把控。粒度太大,职责不单一,导致低内聚、高复杂度的脆弱代码。粒度太小,导致间接层次多,高耦合,同样脆弱。如何把控粒度,真是一门艺术。

一码总结了两条把控粒度的方法,尝试给你说清楚。

面向可控的设计

控制的是复杂度,把多个复杂的问题耦合到一个类甚至一个方法内,这可不是线性增长,是指数增长。三个复杂度为N的问题耦合到一起,复杂度变成了N^3,而不是3N。

继续拿“词频统计”来说事,如果不把大数据处理抽离形成基础框架,那一个“统计词频”实现出来就要上万行代码,估计天也看不懂这是要统计词频。以后要再加上按词频排序输出的功能,估计想死的心都有了。

提示: 一个类最多只实现一个复杂逻辑,把复杂度的指数增长变成线性增长。

解决这类问题的重构手法就是提取类,《大话重构》前面的文章已介绍多次,就不再多说了。

面向扩展的设计

可扩展的重要性不言而喻。扩展是针对技术和业务趋势而言的,要有前瞻性。如果有类似“会有更好的框架”,“多种算法”等等的情况,一定要发挥你的设计才能,预留相应的扩展点。

发现了扩展点,就要做成接口,剥离相关实现。这是设计模式擅长的事情,不展开,后续一码会系列文章“大话”设计模式。

提示: 针对技术和业务趋势,预留扩展点,并剥离扩展点的实现。

只有两条,有更多想法的小伙伴,一定不要吝啬告诉一码。

狂言重构 之 职责单一原则真的简单吗

职责单一是门不断发展的艺术

软件业发展如此多年,职责单一原则 其实也一起发展了这么多年,只是你可能没注意到,一码来说说。

Java,一处编写,跨平台到处运行,把平台差异从业务代码中剥离了吧,是职责问题。

FP,函数式编程,比如C#的Linq,Scala语言等等,相当重要的一点在于剥离控制逻辑和业务逻辑,是职责问题吧。

AOP,面向方面编程,把日志、性能统计从业务代码中剥离,把衍生逻辑从主业务逻辑剥离,是职责问题吧。

SOA,面向服务的架构。2002年亚马逊CEO贝佐斯强制推行SOA,谁不服开除谁。SOA直接用服务和协议封装了业务和数据,更彻底,保证了模块级的职责单一。

各种框架。HDFS封装了大数据的分布式存储,并保证高可用,你可以用类似于Linux文件管理的命令来访问它们;Spark封装了大数据处理,并提供简洁的API,你可以以接近写本地代码的方式,处理整个集群里面的数据。。。它们把难于彻底掌握,需要花费大量精力理解的技术需求剥离出来,放到幕后,你只关心业务逻辑即可,还是职责问题。

感觉duang的一声,原来整个世界都是在解决职责问题。职责单一原则 这门艺术真伟大,不过可以肯定,明天更伟大。

小伙伴们,下一期见。

推荐

解决万恶之首“重复代码”

消除过长方法

消除巨无霸类

答读者问

你的参数列表像蚯蚓一样让人厌恶吗

职责单一原则真的简单吗

查看《大话重构》系列文章,请进入YoyaProgrammer公众号,点击 核心技术,点击 大话重构。

分类 大话重构

优雅程序员 原创 转载请注明出处

狂言重构 之 职责单一原则真的简单吗