1)根据要解决的问题来设计线程或者类体系,保证带来的复杂性都是因为问题的复杂性而带来(用多线程可带来好处的地才使用),并且要试图从技术上尽量缩减方案的复杂性(比如用JDK5新线程代替原来wait,notify)。(数据迁徙重构有感)
针对代码:要思考多这几个类解决了什么问题,多几个线程又解决了什么问题,深层次的调用又解决了什么问题,如果没有解决什么问题,只是复杂,还是删除掉吧。
2)重构代码要有自动测试护航,哪怕是只有验收测试。
3)写足够少的代码,保证每小步都可执行,可观测,在每次小正确时考虑是否要重构。
顺序,先写接口,再写接口测试,测试失败,接口实现,测试通过,考虑重构。
就像是想做一个东西,组装一个东西,先做零件,想合起来时就合起来,不想合时就做部分。单个零件都有单元测试或者集成测试保证,合起来有验收测试来保证。做了一些再看看这些是不是搭,不搭就可以重构。
4)日志记录一定要有类名,方法名,及代码执行到此的副作用说明
5)如果原代码不错,改动原来代码一般要遵守原来代码的风格,如果相反,则应该尽可能在时间允许的范围尽量改动原代码。
6)如果要用设计来体现代码,如果程序使用面向对象思想来设计的,可以用类图来很好的表达,如果程序是面向过程开发的,用流程图来表达更容易些。
7)代码,是追求逻辑流程的清晰,还是追求代码的简洁是一个取舍,但清晰不是代码繁琐的借口。
8)主体功能用面向对象,细节用面向过程。
9)如果不能做到完美,抽取公共代码的最低限度,最容易改变的地方一定要抽取出来。
10)构造函数用于保证必须有的状态,可以防止程序出现意外的错误,增加代码可读性。
11)大多数互联网公司更关心软件的质量属性,而非业务建模。
12)重复代码抽取
代码:出现重复代码,但又不完全一样。
a 把不一样的地方抽象化,就一样了。
b 不一样的地方可以抽象成抽象方法或者接口
c 合并公共代码,不一样的地方用子类或者实现接口的方式来实现。
13)上线
调用其它人的接口一定要把日志打详细
如果程序对CPU或内存要求比较高,一定要在测试环境和线上查看CPU或内存占用率。
14)日志
日志可读性要好,比如多线程程序,一定要打印出线程的名字,要易读,如th-1。
如果监控内容中包含字符串,要能显示出两边是否有空格,比如两边加括号(aaa)。
15)代码自检
在自己审核代码时经常看不下去,感觉都没问题,但如果有问题,带来的代价比想象中的要大的多,带着这样的心态去审核自己的代码。当然有JUnit测试更放心些,但代码自检还是有自己的意义。