怎样写好代码
内容提要:
- 建立准确的职业观
- 编码与设想
- 编程价值观
- 什么是好的代码
- 代码的坏滋味
- 怎样重构
一、建立准确的职业观
1)写代码这份事变,可以干多久?
问:是吃芳华饭的玩意 答:我立时就不编码了,没意思!
甲:你事变多久了? 乙:六年吧! 甲:靠,六年了,你还在写代码啊? 乙:汗。。。。。。
2)写代码的,就是软件蓝领?
甲:近来,混得怎样?据说,你还在写代码啊? 乙:滚,你才在写代码呢,你百口都在写代码!
3)写代码的,路在何方?
- 不要被成为项目经理,不要被成为架构师
- 实在,我们可以一直在编码!
二、编码与设想
1)设想高于代码?
甲(架构师):这个设想我已悉数完成了,你们编码吧!这个礼拜完成! 乙们:老大,一个礼拜搞不定啊! 甲:为何? 乙们:这个设想,有点彷佛问题啊??根据你的设想,有很多细节,没斟酌到啊。 甲:细节?那是你们程序员的事变。我是做架构的! 乙们:无语了:cry::cry::cry:(再问就继续被蔑视了)
2)最好的设想经常是在编码阶段发生的
编程前做设想这类思绪是没错的 , 然则设想后不该该就以为该模子就是使命的最好设想 . 你会发明最好的设想是你在编码阶段 , 一步一步逐步构成的 。
3)真正的牛人是怎样说的:
- 设想看作软件开发的关键环节, 而把编程看作机械式的初级劳动 。设想就像画工程图纸而编码就像施工 。然则这是毛病的 !!!!! 软件的可塑性更强 ,而且完全是头脑产物。
- 一些项目中,设想或许可能会细致到可以让编码事变近乎机化,但很少有云云完全的设想 —— 程序员 ( 指编程 ) 平常也要部份程序举行设想,或许是正式的,或许不是。
- 有了设想 , 我可以编程更快 , 但个中充溢小破绽 -Alistar Cockburn
- 什么是软件设想? -- 代码也是设想 © Jack W.Reeves , 1992
- 软件系统源代码是它的重要设想文档 , 用来形貌源代码的图示只是设想的附属物而不是设想本身 . 你不该该以为设想就是一组和代码星散的 UML 图 .
三、 编程价值观
1)评价规范的背地结果-----关注开发总本钱
Costtotal=Costdevelop+Costmaintain
----Edward Yourdon&Larry L. Constantine
2)软件系统保护事变量所占的比重超越设想!!!!!!!!
Costmaintain=Costunderstand+Costchange+Costtest+Costdeploy
Costmaintain>>Costdevelop
3)代码要人可以读懂------Martion Fowler
任何一个傻瓜都能写出机械能懂的代码,好的程序员应该写出人 能懂的代码。
----Martin Fowler 《重构》
4)程序员要有这类认识------"写烂代码要遭报应!!!!!!!!!"
编程的时刻,老是想着谁人保护你代码的人会是一个晓得你住在 哪儿的有暴力偏向的精神病患者。
----Martin Golding
5)软件代码3项职责------Robert C Martin <迅速软件开发>
- 第1职责:运转起来所完成的功用,这是模块存在的缘由。
- 第2职责:要和浏览它的人举行沟通,对模块不熟悉的职员应该可以比较轻易明白。
- 第3职责:它要应对变化,由于软件要变化,开发者保证应该只管的简朴。
6)价值观是编程历程的一致安排性主题.有3个价值观:
- 沟通:珍爱与他人沟通的重要性
- 简朴:把过剩的的庞杂性去掉
- 天真:坚持开放,应对变化
——Kent Beck
7)整齐代码------百花怒放
跟着岁数的增进,我逐步意想到编程不仅仅是让程序运转罢了; 编程是制造一个易于明白的、可以保护的、高效的作品。平常来 说,清洁整齐的代码,每每运转起来更快。这与盛行看法恰好相 反。而且纵然它们不快,也可以很轻易地让它们变快。正如人们 所说的,优化准确的代码比纠正优化过的代码轻易多了。
---- Google公司首席Java架构师Joshua Bloch
我喜好文雅和高效的代码。代码逻辑应该直接了当,叫缺点难 以隐蔽;只管削减依靠关联,使之便于保护;根据某种分层战 略完美毛病处理代码;机能调至最优,免得诱惑他人做没规矩 的优化,搞出一堆混瞎搅。整齐的代码只做好一件事。
----Bjarne Stroustrup, inventor of C++ and author of The C++
整齐的代码简朴直接。整齐的代码犹如幽美的散文。整齐的代 码从不隐蔽设想者的希图,充溢了清洁利落的笼统和直接了当 的掌握语句
----Grady Booch,Object Oriented Analysis and Design with Applications
p整齐的代码应可由作者以外的开发者浏览和补充。它应该有单 元测试和验收测试。它运用有意义的定名。它只供应一种而非 多种做一件事的门路。它只要只管少的依靠关联,而且要明白 地定义和供应清楚、只管少的API。代码应经由过程其字面表达含 义,由于差别的言语致使并不是一切必须信息都可经由过程代码本身 清楚表达
----“老大”Dave Thomas,OTI公司创始人,Eclipse计谋教父
我可以列出我留意到的整齐代码的一切特性,但个中有一条是根 本性的。整齐的代码老是看起来像是某位迥殊在乎它的人写的。 几乎没有革新的余地。代码作者什么都想到了,假如你希图革新 它,总会回到原点,赞叹或人留给你的代码—全心投入的或人留 下的代码。
----Michael Feathers,Working Effectively with Legacy Code
四、什么是好的代码
1)为何要写好的代码
几种主意:
- 我立时就去职了,横竖,这块代码我不保护了
出来混迟早是要还的,你总有一天会保护到一样的代码
- 原本这个就不该该是我做的,我已很疲劳了
软件开发界的别的一个小秘密是:编写优异代码和蹩脚代码所消费的时候是一样多。一名训练有素的工程师,他/她会从第一行代码入手下手就斟酌可保护性和代码 的演变。没有任何理由编写“貌寝”的代码、长达数页的函数,或是八怪七喇的变量名。
- 我就这程度,还不晓得怎样写出好的代码
看书、进修、多实战
2)好代码的重要性
- 下降保护本钱
- 有助于程序员本身生长
- 有用增进团队协作,加深小伙伴友情
3)究竟什么是好的代码?
不坏的代码就是好代码-----这不是空话
五、代码的坏滋味
第一级
- Duplicated Code(反复代码)
- Long Method(太长函数)
- Large Class(过大类)
- Long Parameter List(太长参数)
- Comments(过量的解释)
- Temporary Field(使人疑惑的暂时值域)
- Primitive Obsession(基础型别偏执狂)
- Switch Statements(Switch惊悚现身)
- Divergent Change(发散式变化)
- Shotgun Surgery(散弹式修正
第二级
- Data Clumps(数据泥团)
- Data Class(稚子的数据类)
- Feature Envy(陶醉情结)
- Refused Bequest(被谢绝的遗赠)
- Message Chains(过分耦合的音讯链)
- Middle Man(中心转手人)
- Inappropriate Intimacy(狎昵关联)
- Lazy Class(冗余类)
第三级
- Parallel Inheritance Hierarchies(平行继续)
- Speculative Generality(理论上的平常性)
- Alternative Classes with Different Interfaces(殊途同归类)
- Incomplete Library Class(不完美的程序库类)
六、怎样重构
代码的坏滋味 | 平常重构要领 | 运用形式重构 |
---|---|---|
反复代码 | 提炼要领 | 组织Template Method 以Composite庖代一/多之分 引入Null Object 用Adapter一致接口 用Fatory Method引入多态建立 |
提取类 | ||
要领上移 | ||
替代算法 | ||
链组织要领 | ||
太长要领 | 提取要领 | 转移聚集操作到Vistor 以Strategy庖代前提逻辑 以Command庖代前提调理程序 转移聚集操作到Collecting Parameter |
组合要领 | ||
以查询庖代暂时变量 | ||
引入参数对象 | ||
坚持对象完全 | ||
太长参数列 | 以要领庖代参数 | |
引入参数对象 | ||
坚持对象完全 | ||
前提逻辑过分庞杂 | 剖析前提式 | 以Strategy庖代前提逻辑 转移装潢功用到Decorator 以State庖代状况转变前提语句 引入Null Object |
兼并前提式 | ||
兼并反复的前提片断 | ||
移除掌握标记 | ||
以卫语句庖代嵌套前提式 | ||
以多态庖代前提式 | ||
引入断言 | ||
分支语句 | 提取要领 | 以State/Strategy庖代范例代码 引入Null Object 以Command替代前提调理程序 转移聚集操作到Visitor |
转移要领 | ||
以子类庖代范例代码 | ||
以多态庖代前提式 | ||
已明白要领庖代参数 | ||
基础范例陶醉 程序代码过于依靠基础范例(int,string,double,array等低层次言语要素) | 以对象庖代数据值 | 以State庖代状况转变前提语句 以Strategy庖代前提逻辑 以Composite庖代隐含树 以Interpreter庖代隐式言语 转移装潢功用到Decorator 用Builder封装Composite |
以范例庖代范例代码 | ||
以子类庖代范例代码 | ||
提取类 | ||
引入参数对象 | ||
以对象庖代数组 | ||
数据泥团 在类的字段和参数列中,老是一同涌现的数据 | 提取类 | |
引入参数对象 | ||
坚持对象完全 | ||
使人疑惑的暂时字段 | 提取类 | 引入Null Object |
组合爆炸 很多段代码运用差别品种或数目的数据 或对象做一样的事变(比方运用特定前提和数据库查询) | 以Interpreter庖代隐式言语 | |
过大类 | 提取类 | 以Command庖代前提调理程序 以State庖代状况转变前提语句 以Interpreter庖代隐式言语 |
提取子类 | ||
提取接口 | ||
复制被看管数据 | ||
冗赘类 不再做很多事变或没有用的类 | 折叠继续关联 | |
内联Singleton | ||
不适当的暴露 在客户代码中不该看到类的字段和要领,倒是公然可见的 | 封装字段 | 用Factory封装类 |
封装聚集 | ||
移除设置要领 | ||
隐蔽要领 | ||
发散式变化 类经常由于差别的缘由在差别方向上发生变化,显然是违反了单一职责准绳 | 提取类 | |
霰弹式修正 假如碰到变化,必须在差别的类中作出响应的修正 | 转移要领 | 将建立学问搬移到Factory |
转移字段 | ||
内联类 | ||
陶醉情结 要领关于某个类的兴致高过对本身所处的宿主类 | 转移要领 | 引入Strategy 引入Visitor |
提取要领 | ||
平行继续系统 当为一个类增添一个子类时,也必须在另一个类中增添一个响应的子类 | 转移要领 | |
转移字段 | ||
纸上谈兵将来性 | 折叠继续关联 | |
内联类 | ||
移除参数 | ||
移除要领 | ||
过分耦合的音讯连 不停的向一个对象索求另一个对象 | 隐蔽托付 | 运用笼统引入Chain Of Responsibility |
提取要领 | ||
转移要领 | ||
中心转手人 类之间相互依靠于其private成员 | 移除中心转手人 | |
内联要领 | ||
以继续庖代托付 | ||
狎昵关联 类之间相互依靠于其private成员 | 转移要领 | |
将双向关联改成单向 | ||
提取类 | ||
隐蔽托付 | ||
以继续庖代托付 | ||
殊途同归的类 | 重定名要领 | 用Adapter一致接口 |
转移要领 | ||
提取超类 | ||
不完美的程序库类 | 引入外加要领 | 用Adapter一致接口 用Facade封装类 |
引入当地扩大 | ||
纯稚的数据类 只具有字段的数据类 | 封装字段 | |
封装鸠合 | ||
移除设置要领 | ||
转移要领 | ||
隐蔽要领 | ||
被谢绝的遗赠 继续父类时,子类想要挑选继续的成员 | 以托付庖代继续 | |
过量的解释 为蹩脚的代码写大批的解释 | 运用一同重构要领,使要领本身到达自申明的结果,让解释显得过剩 | |
奇异处理方案 在统一系统中运用差别的体式格局处理统一问题 | 替代算法 | 用Adapter一致接口 |
引见几本好书:
- 《代码整齐之道》----Robert C. Martin
- 《迅速软件开发:准绳、形式与实践》----Robert C. Martin
- 《代码大全》 ----Steve McConnell
- 《重构——改良既有代码的设想》 ----Martin Fowler