如何写好代码
2020/2/18 17:00:39
本文主要是介绍如何写好代码,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
内容提纲:
- 树立正确的职业观
- 编码与设计
- 编程价值观
- 什么是好的代码
- 代码的坏味道
- 如何重构
一、树立正确的职业观
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
这篇关于如何写好代码的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-24Java中定时任务实现方式及源码剖析
- 2024-11-24Java中定时任务实现方式及源码剖析
- 2024-11-24鸿蒙原生开发手记:03-元服务开发全流程(开发元服务,只需要看这一篇文章)
- 2024-11-24细说敏捷:敏捷四会之每日站会
- 2024-11-23Springboot应用的多环境打包入门
- 2024-11-23Springboot应用的生产发布入门教程
- 2024-11-23Python编程入门指南
- 2024-11-23Java创业入门:从零开始的编程之旅
- 2024-11-23Java创业入门:新手必读的Java编程与创业指南
- 2024-11-23Java对接阿里云智能语音服务入门详解