1、敏捷开发是在什么样的背景下产生的?其主要特点有哪些?什么时候选择敏捷开发更恰当,为什么?
2、Code smell 是如何产生的?有哪些典型的 code smell?代码重构(Code refactoring)有哪些优点?有哪些代码重构的方法?
1、敏捷开发是在什么样的背景下产生的?其主要特点有哪些?什么时候选择敏捷开发更恰当,为什么?
(1)产生的背景
传统开发方法是基于客户能够在需求阶段就给出完整、准确的需求的假设,所有期望在项目初期获得详细的需求,然后严格控制需求变更,最终完成符合需求的软件。但我们发现实际上往往需求是“涌现”出来的,也就是说随着开发的不断进展而不断发现出来的,而无法再项目初期就明确的定义它,,也就是说传统开发方法的基本假设是错误的,这一新的假设导致了敏捷方法的一系列实践。另外,传统的软件开发方法认为需求是可以确定,所以采用的是基于工程的开发方法,也就是说期望通过事先的详细策划定义开发的整个过程,而敏捷认为需求是无法再早期完全确定的,所以采用的是基于经验的开发二店方法,也就是是事先不详细定义整个开发过程,而通过多次迭代来逼近最终目标。
(2)主要特点:
(1)敏捷开发方法是“适应性”(Adaptive)而非“预设性”(Predictive)。这里说的预设性,可以通过一般性工程项目的做法理解,比如土木工程,在这类工程项目实践中,有比较稳定的需求,同时建设项目的需求也相对固定,所以此类项目通常非常强调施工前的设计规划。只要图纸设计得合理并考虑充分,施工队伍可以完全遵照图纸顺利建造,并且可以很方便地把图纸划分为许多更小的部分交给不同的施工人员分别完成。
然而,在软件开发的项目中,这些文档的因素却很难寻求。软件的设计难处在于软件需求的不稳定,从而导致软件过程的不可预测。但是传统的控制项目模式都是试图对一个软件开发项目在很长的时间跨度内做出详细的计划,然后依计划进行开发。所以,这类方法在不可预测的环境下,很难适应变化,甚至是拒绝变化。
与之相反的敏捷方法则是欢迎变化,目的就是成为适应变化的过程,甚至能允许改变自身来适应变化。所以称之为适应性方法。
(2)敏捷开发方法是“面向人”(people oriented)而非“面向过程”(process oriented)。
在传统的软件开发工作中,项目团队分配工作的重点是明确角色的定义,以个人的能力去适应角色,而角色的定义就是为了保证过程的实施,即各人以资源的方式被分配给角色,同时,资源是可以替代的,而角色吧可以替代。然而,传统软件开发的这些方法在敏捷开发方式中被完全颠覆。敏捷开发试图使软件开发工作能够利用人的特点,充分发挥人的创造能力。
敏捷开发的目的是建立起一个项目团队全员参与到软件开发中,包括设定软件开发流程的管理人员,只有这样软件开发流程才有可能接受性。同时敏捷开发要求研发人员独立自主在技术上进行决策,因为他们是最了解什么技术是需要和吧需要的。再者,敏捷开发特别重视项目团队中的信息交流,有调查显示:“项目失败的原因最终都可追溯到信息没有及时准确地传递到应该接受它的人。”
(3)何时选择敏捷开发:只适用于小组织和需求不确定易挥发、有责任感和积极向上的开发人员。因为敏捷开发的可靠性不高,一些大的项目开发需要高标准、高质量,对这些大的项目来说,风险太大,所以小组织用比较合适。
2、Code smell 是如何产生的?有哪些典型的 code smell?代码重构(Code refactoring)有哪些优点?有哪些代码重构的方法?
(1)Code Smell中文译名一般为“代码异味”,或“代码味道”,它是提示代码中某个地方存在错误的一个暗示,开发人员可以通过这种smell(异味)在代码中追捕到问题。代码不规范,比如有重复代码等就会形成code smell。
(2)典型的code smell:
(1)Duplicated Cod(重复代码); (2) Long Metnod(过长函数);
(3) Long Class(过大的类); (4)Long Parameter List(过长的参数列);
(5) Divergent Changge(发散式变化); (6)Shotgun Surgery(散弹式修改);
(7)Feature Envy(依恋情结); (8) Data Clumps(数据泥团);
(9)primitive obsession(基本类型偏执); (10)switch statement (switch 惊悚现身);
(11)parallel inheritance jierarchies(平行继承体系); (12) lazy classv(冗赘类);
(13)speculative generality(夸夸其谈未来性); (14) temporary field(令人迷惑的暂时字段);
(15) message chain(过度耦合的消息链); (16) middle man(中间人);
(17)inappromriate intimacy(狎昵关系); (18) alternative classes with different interface(异曲同工的类);
(19)incomplete library class(不完美的库类); (20)data class(纯稚的数据类);
(21)refused bequest(被拒绝的遗赠); (22) comments(过多的注释)。
(3)优点:
能改进软件设计;使软件更容易理解;能帮助发现隐藏的代码缺陷,找到bug,优化代码,提高软件的开发速度,从而提高系统的稳定性,
和可扩展性;能提高编程效率。
(4)代码重构的方法:
(a) 提取类/抽离方法:
正如上面提到的,像“臃肿的类”(一个类提供了本该有几个类提供的功能)这种代码异味应该将原有类中的方法和属性移动到适当数目的新类中去。旧类中对新类的方法和属性应该被移除。另外,有时候一些类过于臃肿是因为它包含了被其他类使用本应该是其他类的成员方法的成员方法。这些方法也应该被迁移到合适的类中。
(b)提取方法:
像上面提到的“过长的方法”这种代码异味可以通过从旧方法中提取代码到应该或多个新方法中消除。
(c)分离条件:
许多时候,一个方法很长是因为包含好几个语句(if-else)。这些分支条件可以被提取和移动到几个单独的方法中。这确实能大大改善代码可读性和可理解性。
引入参数对象/保留全局对象:在我做代码审查时发现另外一个很常见的情况-好几个参数被引入方法。问题主要与需要从已有方法中增加或者消除一个方法参数有关。
在这种 场景,建议将相关方法参数组成一个对象(引入参数对象),让方法传递这些对象而不是每个单独的参数。
(d)用符号常量替换魔法数字:
对于有意义的并且到处被使用的字面常量,应该为他买分配一个命名常量。这样大大增强代码可读性和可理解性。
(e)重命名方法:
正如上面提到的,模糊不清的方法名会影响代码的可使用性。这些模糊不清的名称应该重命名为有意义的可能与业务术语有关的名称,来帮助开发者已通过业务上下文更好地理解代码。这很需要技巧并且要求开发者与业务专家一起协作来理清嗲吗需要满足的业务需求。有趣的是,这种重构方法看起来似乎非常容易理解,但是常常被许多开发者忽视,,虽然在Elipse这种IDE的refactor菜单项中经常出现这一项。