代码的坏味道
…
老外没有艺术细胞,作为一名大师级任务,好歹给起个好听点的名称。向金庸老人家学习下,让我们也感染下艺术气息。
我认为吗,坏味道就是对一段问题代码的感觉,从感性慢慢分析到理性。这种感觉需要在实践中培养。观看这里的介绍只能有个大概的理解方向,只有在反复在实际的代码中去体会,才能运用自如。
我也是爱国人士,也很不喜欢英语,不过毕竟都是老外的东西,为了避免一些名词的混淆,我还是用英语加翻译的方式。
一、
重复代码(
Duplicated Code
)
很直观的一个问题,就算新手也很快能看出。如果是同一个类里面有重复代码,使用
Extract Method
(提炼函数)把重复的给提取出来;如果重复代码分别在一个类的两个子类中,则先提取代码,然后使用
Pull Up Method
(函数上移)把提取的函数放到
superclass
中;如果在好不相干的两个类中,则考虑使用
Extract Class
(提炼类)把重复代码独立成一个类,也可以把函数放在其中一个类中,另一个应用这个之,看实际情况了。
二、
过长函数(
Long Method
)
看
50
行的
20
个函数比看一千行的一个函数强多了,所以么函数不宜过长,或者说就应该短,
java
在调用函数时候的开销很小,一般不会产生性能问题。我也讨厌那些长函数,看到后面逻辑都乱了,本人见过两千行的函数,唉,一半注解一半代码。
99%
的场合只需要使用
Extract Method
(提炼函数)。如果函数内有大量的参数和临时变量,可以尝试
Extract Method
(提炼函数)把那些参数和临时变量当作参数,运用
Replace Temp With Query
(以查询取代临时变量)来消除暂时元素。
Introduce Parameter Object
(引入参数对象)和
Preserve Whole Object
(保持对象完整)则可以把过长的参数变简洁。如果做完上述发现还是有太多参数和变量,可以使用杀手锏:
Replace Method With Method Object
(以函数对象取代函数)。条件和循环常常是提取的信号,可以使用
Decompose Conditional
(分解条件式)来处理条件式。循环则可以提炼一个独立的函数。
三、
过长类(
Large Class
)
这种可以使用
Extract Class
(提炼类)提炼出内容有相关性的。如果类里面有数个变量有着一样的前缀或后缀,用
Extract Subclass
(提炼子类)会比较简单。如果是
GUI
类,可以把数据和行为移到单独的
domain
对象中去,运用
Duplicate Observed Data
(复制被监视数据)同步数据。
四、
过长参数列(
Long Parameter List
)
过长的参数列往往难以理解,还可能造成前后不一致,一旦需要更多数据,就不得不修改它。如果“向既有对象发出一条请求”就能取得原本位于参数列上的数据时,就可以使用
Replace Parameter With Method
(以函数取代参数)。还可以运用
Preserve Whole Object
(保持对象完整)将来自同一对象的一堆数据收集起来,并以该对象替换参数。如果默写参数缺乏合理的对象归属,可以使用
Introduce Parameter Object
(引入参数对象)为他们制造出一个参数对象。当然也有例外,如果不希望两个类之间出现依赖关系,可以把数据从对象里面拆解出来,单独作为参数。
五、
发散式变化(
Divergent Change
)
发散式变化是指一个类经常因为不同原因在不同的方向上发生变化。这个是违反危险对象的开发原则的“一个类应该有且只有一个改变的理由”。这样的类可以运用
Extract Class
(提炼类)将那些同一个原因变化的部分提炼到另一个类中。
六、
霰弹式修改(
Shotgun Surgery
)
这个问题恰恰与发散式变化相反,一个变化经常需要去修改多个类。这种问题会导致修改的代码散步四处,出错的几率会变大。可以使用
Move Method
(移动函数)和
Move Field
(移动值域)把所有需要一同修改的代码放到同一个类。通常可以运用
Inline Class
(将类内联化)把一系列相关行为放进同一个类。
七、
依恋情结(
Feature Envy
)
好晦涩难懂的名字。这个问题是指一个函数对另一个类的兴趣高过自己所在的类。这种问题很简单,使用
Move Method
(移动函数)方法把函数移到它该去的地方。如果只有函数中的部分代码有这个问题,那么先使用
Extract Method
(提炼函数),然后在
Move Method
(移动函数)。当然也有些设计模式不适合这个原则,比如
Strategy
和
Visitor
。
八、
数据泥团(
Data Clumps
)
我的理解是扎堆一起出现的数据(变量、参数等),且在不止一处(不同的类中或是同一个类中)出现,这些应该放进属于他们自己的对象中。在数据值域出现的地方,用
Extract Class
(提炼类)将他们提炼到一个独立对象中,然后
Introduce Parameter Object
(引入参数对象)或
Preserve Whole Object
(保持对象完整)为原有代码减肥。
九、
基本型别偏执(
Primitive Obsession
)
看来我语文水平不好,看到这种词我都无法理解。只能慢慢读内容才可以看懂。基本类别偏执:喜欢或钟爱使用基本类型而不愿意使用对象,想着基本类型效率要比使用对象高(至少基本类型小)。不过这样势必带来了一些麻烦,比如太多的变量在函数中。可以运用
Replace Data Value with Object
(以对象取代数据值)将原本单独存在的数据替换为对象。如果替换的数据值是
type code
(类别码),而它不影响行为,可以使用
Replace Type Code with Class
(以类取代型别码)将它换掉。如果有相依于此的
type code
的条件式,可以用
Replace Type Code with Subclass
(以子类取代型别码)或
Replace Type Code with State/Strategy
(以
State/Strategy
取代型别码)加入处理。如果是一组这样的数据,可以参考数据泥团的解决。
十、
Switch
惊悚现身(
Switch Statements
)
Switch
是代码中比较少用到的,但是不是不会用到,一般我也不忌讳用这个。不过书中说面向对象开发中应该少用它,挺费解的。
一看到
switch
就考虑多态来替换。用
Extract Method
(提炼函数)将
switch
语句提炼出来,再用
Move Method
(移动函数)将它移到需要多态性的那个类里头。此时必须决定是否使用
Replace Type Code with Subclasses
(以子类取代型别码)或
Replace Type Code with State/Strategy
(以
State/Strategy
取代型别码)。完成继承结构后就可以用
Replace Conditional with Polymorphism
(以多态取代条件式)了。
如果只是单一函数中有些选择事例,那就不用多态这把牛刀了。这种情况可以用
Replace Parameter with Explicit Methods
(以明确函数取代参数)。如果条件之一是
null
,可以试试
Introduce Null Object
(引入
null
对象)。
十一、
平行继承体系(
Parallel Inheritance Hierarchies
)
这种情况下为某个类增加一个子类的时候,必须同时为另一个类相应的增加一个子类。消除这种重复性的一般策略是:让一个继承体系的实体指涉(参考、引用、
refer to
)另一个继承体系的实体。如果再接再厉,运用
Move Method
(提炼函数)和
Move Field
(移动值域),就可以将指涉端的继承体系消弭与无形。
十二、
冗赘类(
Lazy Class
)
十三、
夸夸其谈未来性(
Speculative Generality
)
十四、
令人迷惑的暂时值域(
Temporary Field
)
十五、
过度耦合的消息链(
Message Chains
)
十六、
中间转手人(
Middle Man
)
十七、
狎昵关系(
Inappropriate Intimacy
)
十八、
异曲同工的类(
Alternative Classes with Different Interfaces
)
十九、
不完美的程序库类(
Incomplete Library Class
)
二十、
纯稚的数据类(
Data Class
)
二十一、
被拒绝的遗赠(
Refused Bequest
)
二十二、
过多的注解(
Comments
)
实在写不动了。话说这么多坏味道,一个一个记住,不是什么好主意。还是先理解这些,然后在遇到的时候去看下书本。话说我有这本书的
chm
格式的电子书。
再接再厉的学习。剩下的有时间补上。
分享到:
相关推荐
内容概要:本文详细介绍了基于MATLAB GUI界面和卷积神经网络(CNN)的模糊车牌识别系统。该系统旨在解决现实中车牌因模糊不清导致识别困难的问题。文中阐述了整个流程的关键步骤,包括图像的模糊还原、灰度化、阈值化、边缘检测、孔洞填充、形态学操作、滤波操作、车牌定位、字符分割以及最终的字符识别。通过使用维纳滤波或最小二乘法约束滤波进行模糊还原,再利用CNN的强大特征提取能力完成字符分类。此外,还特别强调了MATLAB GUI界面的设计,使得用户能直观便捷地操作整个系统。 适合人群:对图像处理和深度学习感兴趣的科研人员、高校学生及从事相关领域的工程师。 使用场景及目标:适用于交通管理、智能停车场等领域,用于提升车牌识别的准确性和效率,特别是在面对模糊车牌时的表现。 其他说明:文中提供了部分关键代码片段作为参考,并对实验结果进行了详细的分析,展示了系统在不同环境下的表现情况及其潜在的应用前景。
嵌入式八股文面试题库资料知识宝典-计算机专业试题.zip
嵌入式八股文面试题库资料知识宝典-C and C++ normal interview_3.zip
内容概要:本文深入探讨了一款额定功率为4kW的开关磁阻电机,详细介绍了其性能参数如额定功率、转速、效率、输出转矩和脉动率等。同时,文章还展示了利用RMxprt、Maxwell 2D和3D模型对该电机进行仿真的方法和技术,通过外电路分析进一步研究其电气性能和动态响应特性。最后,文章提供了基于RMxprt模型的MATLAB仿真代码示例,帮助读者理解电机的工作原理及其性能特点。 适合人群:从事电机设计、工业自动化领域的工程师和技术人员,尤其是对开关磁阻电机感兴趣的科研工作者。 使用场景及目标:适用于希望深入了解开关磁阻电机特性和建模技术的研究人员,在新产品开发或现有产品改进时作为参考资料。 其他说明:文中提供的代码示例仅用于演示目的,实际操作时需根据所用软件的具体情况进行适当修改。
少儿编程scratch项目源代码文件案例素材-剑客冲刺.zip
少儿编程scratch项目源代码文件案例素材-几何冲刺 转瞬即逝.zip
内容概要:本文详细介绍了基于PID控制器的四象限直流电机速度驱动控制系统仿真模型及其永磁直流电机(PMDC)转速控制模型。首先阐述了PID控制器的工作原理,即通过对系统误差的比例、积分和微分运算来调整电机的驱动信号,从而实现转速的精确控制。接着讨论了如何利用PID控制器使有刷PMDC电机在四个象限中精确跟踪参考速度,并展示了仿真模型在应对快速负载扰动时的有效性和稳定性。最后,提供了Simulink仿真模型和详细的Word模型说明文档,帮助读者理解和调整PID控制器参数,以达到最佳控制效果。 适合人群:从事电力电子与电机控制领域的研究人员和技术人员,尤其是对四象限直流电机速度驱动控制系统感兴趣的读者。 使用场景及目标:适用于需要深入了解和掌握四象限直流电机速度驱动控制系统设计与实现的研究人员和技术人员。目标是在实际项目中能够运用PID控制器实现电机转速的精确控制,并提高系统的稳定性和抗干扰能力。 其他说明:文中引用了多篇相关领域的权威文献,确保了理论依据的可靠性和实用性。此外,提供的Simulink模型和Word文档有助于读者更好地理解和实践所介绍的内容。
嵌入式八股文面试题库资料知识宝典-2013年海康威视校园招聘嵌入式开发笔试题.zip
少儿编程scratch项目源代码文件案例素材-驾驶通关.zip
小区开放对周边道路通行能力影响的研究.pdf
内容概要:本文探讨了冷链物流车辆路径优化问题,特别是如何通过NSGA-2遗传算法和软硬时间窗策略来实现高效、环保和高客户满意度的路径规划。文中介绍了冷链物流的特点及其重要性,提出了软时间窗概念,允许一定的配送时间弹性,同时考虑碳排放成本,以达到绿色物流的目的。此外,还讨论了如何将客户满意度作为路径优化的重要评价标准之一。最后,通过一段简化的Python代码展示了遗传算法的应用。 适合人群:从事物流管理、冷链物流运营的专业人士,以及对遗传算法和路径优化感兴趣的科研人员和技术开发者。 使用场景及目标:适用于冷链物流企业,旨在优化配送路线,降低运营成本,减少碳排放,提升客户满意度。目标是帮助企业实现绿色、高效的物流配送系统。 其他说明:文中提供的代码仅为示意,实际应用需根据具体情况调整参数设置和模型构建。
少儿编程scratch项目源代码文件案例素材-恐怖矿井.zip
内容概要:本文详细介绍了基于STM32F030的无刷电机控制方案,重点在于高压FOC(磁场定向控制)技术和滑膜无感FOC的应用。该方案实现了过载、过欠压、堵转等多种保护机制,并提供了完整的源码、原理图和PCB设计。文中展示了关键代码片段,如滑膜观测器和电流环处理,以及保护机制的具体实现方法。此外,还提到了方案的移植要点和实际测试效果,确保系统的稳定性和高效性。 适合人群:嵌入式系统开发者、电机控制系统工程师、硬件工程师。 使用场景及目标:适用于需要高性能无刷电机控制的应用场景,如工业自动化设备、无人机、电动工具等。目标是提供一种成熟的、经过验证的无刷电机控制方案,帮助开发者快速实现并优化电机控制性能。 其他说明:提供的资料包括详细的原理图、PCB设计文件、源码及测试视频,方便开发者进行学习和应用。
基于有限体积法Godunov格式的管道泄漏检测模型研究.pdf
嵌入式八股文面试题库资料知识宝典-CC++笔试题-深圳有为(2019.2.28)1.zip
少儿编程scratch项目源代码文件案例素材-几何冲刺 V1.5.zip
Android系统开发_Linux内核配置_USB-HID设备模拟_通过root权限将Android设备转换为全功能USB键盘的项目实现_该项目需要内核支持configFS文件系统
C# WPF - LiveCharts Project
少儿编程scratch项目源代码文件案例素材-恐怖叉子 动画.zip
嵌入式八股文面试题库资料知识宝典-嵌⼊式⼯程师⾯试⾼频问题.zip