《重构》读书笔记(3)

代码的坏味道

1、Duplicated Code(重复代码)

    1)同一个类的两个函数含有相同的表达式
        提炼重复的代码,然后让两个函数都调用被提炼出来的那一段代码。

    2)两个互为兄弟的子类内含有相同的表达式
        对两个类都进行代码提炼,然后将被提炼出来的代码中相似部分和差异部分分割开,构成单独一个函数。然后你可能发现可以运用From Template Method(345)获得一个Template Method设计模式。
        如果有些函数以不同的算法做相同的事,你可以选择较清晰的一个,并使用Substitude Algorithm将其他函数的算法替换掉。

    3)两个毫不相干的类出现Duplicated Code
        应该考虑对其中一个类提炼代码,将重复代码提炼到一个独立类中,然后在另一个类中使用这个新类;重复代码也可能应该属于某个类,那么其他类应该引用这个类。

2、Long Method(过长函数)

    通过不停地将代码中具有具体用途的部分提炼出来,可以避免函数过长。遵循一条原则:每当感觉需要写注释来说明点什么的时候,我们就需要说明的东西写进一个独立的函数中,并以其用途(而非实现手法)命名。
    
    1)注释。注释通常能指出代码用途和实现手法之间的语义距离,如果代码前方有一行注释,就可以将这段代码替换成函数。
    2)条件表达式和循环。可以使用Decompose Conditional(238)处理条件表达式;应该将循环内的代码提炼到一个独立的函数中。

3、Large Class(过大的类)

    如果单个类做太多事,往往就会出现太多实例变量,也很容易出现重复代码。
    
    1)提炼子类
        提炼时选择相关的变量、方法,组合成新类。通常如果类内的数个变量有相同的前缀或字尾,意味着有机会提炼到某个组件内。

    2)提炼函数
        如果类中的函数过长,它们之中很多代码相同,那可以把它们提炼成多个的短函数。

    3)提炼接口
        确定客户端如果使用类中代码,为每一种使用方式提炼出一个借口。这可以帮助看清楚如何分割这个类。

4、Long Parameter List(过长参数列)

    坏味道:
    1)难以理解,需要识别各个参数的含义
    2)太多参数很容易造成前后不一致,传递参数出错
    3)如果需求变更,需要更多数据,就不得不修改参数

   解决办法:
    1)将函数作为行为提炼到归属的类中,使用类属性替代参数传递
    2)将多个参数归类,以对象的形式传递给函数

5、Divergent Change(发散式变化)

    坏味道:
    如果某个类经常因为不同的原因,需要修改的地方很多,比如 新增一个数据库、添加一个功能,需要修改多个函数。

    解决办法:
    可以将类提炼拆分成不同的类,针对某一变化的时候,相应修改只发生在一个类中。

6、shotgun Surgery(霰弹式修改)

    坏味道:
    如果遇到某种变化,许多类都要做出许多小修改,很容易忘记某个重要修改。

    解决办法:
    把所有需要修改的代码放进同一个类。如果没有合适的类安置这些代码,就新建一个类。

7、Feature Envy(依恋情结)

    坏味道:
    函数对其它类的依赖性比宿主类还要高,从其它类调用几乎半打的取值函数。

    解决办法:
    将这个函数分解成数个较小函数,判断哪个类拥有最多被此函数使用的数据,然后就把这个函数和那些数据放到一个类。

8、Data Clumps(数据泥团)

    坏味道:
    两个类中有相同的字段;许多函数签名中有相同的参数。

    解决办法:
    找出这些数据以字段出现的地方,运用Extract Class提炼到一个独立的对象中;函数签名上,运用Introduce Parameter Object或Preserve Whole Object为它减肥。这么做的直接好处就是可以将很多参数列缩短,简化函数调用。

9、Primitive Obsession(基本类型偏执)

    对象的概念模糊(设置打破)了横亘于基本数据和体积较大的类之间的界限。
    1)可以运用Replace Data Value with Object(175)将原本单独存在的数据值替换为对象
    2)如果想要替换类型码,而不影响行为,可以运用Replace Type Code with Class(218)将它换掉
    3)如果有与类型码相关的条件表达式,可以运用Replace Type Code with Subclass(213)或Replace Type Code with State/Strategy(227)加以处理

10、Switch Statements(switch惊悚现身)

    坏味道:
    代码中switch语句散布于不同地方,如果要为它添加一个新的case子句,就必须找到所有switch语句并修改它们。

    解决办法:
    1)使用Extract Method将switch语句提炼到一个独立函数中,再以Move Method(142)将它搬移到需要多态性的类中。
    2)如果只是在单一函数中有些选择实例,且并不想改动它们,可以运用Replace Parameter with Explicit Methods(285);如果选择条件之一是null,可以运用Introduce Null Object(260)

11、Temporary Field(令人迷惑的暂时字段)

    坏味道:
    类中某个实例变量仅为某种特定情况而设,这样的代码让人不易理解,因为通常认为对象在所有情况都需要它的所有变量。这种不常用的临时字段,需要猜测当初其设置目的。

    解决办法:
    1)使用Extract Class创建一个类,把所有和这个变量相关的代码放进这个类中。
    2)如果类中有一个复杂算法,需要好几个变量,由于不希望传递以长串参数,所以把这些参数都放进字段中。但是这些字段只在使用该算法时才有效,其它情况容易让人迷惑,这时候可以与用Extract Class把这些变量和其相关函数提炼到一个独立类中。

12、Message Chains(过度耦合的消息链)

    坏味道:
    代码中使用一个对象请求另一个对象,然后再向后者请求另一个对象,然后再请求另一个对象……实际代码中看到的可能是一长串getThis()或一长串临时变量。这种方式意味客户端代码将与查找过程中的导航结构紧密耦合,一旦对象间关系发生任何变化,客户端就不得不修改。

   解决办法:
   先观察消息链最终得到的对象是用来干什么的,看能否以Extract Method把使用该对象的代码提炼到一个独立函数,在运用Move Method把这个函数推入消息链。

13、Inappropriate Intimacy(狎昵关系)    

    坏味道:
    两个类之间互相调用对方的private成员,比如继承往往带来这种依赖关系。

    解决办法:
    1)可以采用Move Method和Move Field,减少降低它们的依赖耦合程度
    2)如果两个类确实依赖性较强,可以运用Extract Class把两者共同点提炼到一个新类;或者运用Hide Delegate(157)让另一个类处理它们之间的关联行为

14、Comments(过多的注释)

    坏味道:
    代码中存在一些长注释,是为了解释一段难以理解的糟糕代码。

    处理办法:
    把被注释的代码进行重构,使代码结构清晰容易理解。
    1)如果注释是用来解释代码做了什么,运用Extract Method把代码块提炼成函数
    2)如果函数已经提炼出来,还需要注释来解释其行为,运用Rename Method使方法名称很易理解其行为
    3)如果需要注释说明某些系统的需求规格,运用Introduce Assertion引入断言。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
目标检测(Object Detection)是计算机视觉领域的一个核心问题,其主要任务是找出图像中所有感兴趣的目标(物体),并确定它们的别和位置。以下是对目标检测的详细阐述: 一、基本概念 目标检测的任务是解决“在哪里?是什么?”的问题,即定位出图像中目标的位置并识别出目标的别。由于各物体具有不同的外观、形状和姿态,加上成像时光照、遮挡等因素的干扰,目标检测一直是计算机视觉领域最具挑战性的任务之一。 二、核心问题 目标检测涉及以下几个核心问题: 分问题:判断图像中的目标属于哪个别。 定位问题:确定目标在图像中的具体位置。 大小问题:目标可能具有不同的大小。 形状问题:目标可能具有不同的形状。 三、算法分 基于深度学习的目标检测算法主要分为两大: Two-stage算法:先进行区域生成(Region Proposal),生成有可能包含待检物体的预选框(Region Proposal),再通过卷积神经网络进行样本分。常见的Two-stage算法包括R-CNN、Fast R-CNN、Faster R-CNN等。 One-stage算法:不用生成区域提议,直接在网络中提取特征来预测物体分和位置。常见的One-stage算法包括YOLO系列(YOLOv1、YOLOv2、YOLOv3、YOLOv4、YOLOv5等)、SSD和RetinaNet等。 四、算法原理 以YOLO系列为例,YOLO将目标检测视为回归问题,将输入图像一次性划分为多个区域,直接在输出层预测边界框和别概率。YOLO采用卷积网络来提取特征,使用全连接层来得到预测值。其网络结构通常包含多个卷积层和全连接层,通过卷积层提取图像特征,通过全连接层输出预测结果。 五、应用领域 目标检测技术已经广泛应用于各个领域,为人们的生活带来了极大的便利。以下是一些主要的应用领域: 安全监控:在商场、银行
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值