读《程序员修炼之道·通向务实的最高境界》思考
这本书真的是值得读两遍以上的,以下内容每句都是精华,值得反复斟酌,它可以教会你怎样从'小工'到'工匠'
第一章 务实的哲学
习惯
- 当你看到不懂的名词时候,请google它
注释
- 已经能表达的代码没必要全部写注释,注释一些思路,选择决定更重要
- 把文档嵌入到工作中,生活中,就像现在记录一样
随记
- 首先让产品看起来不错
- 一定要及时回应别人
- 明白自己想说什么
- 让听众参与其中
- 选择一个较好的时机去诉说
- 关注身边的事情,因为身边的事情是与你相关的
第二章 务实的方法
ETC(Easier To Change)
- 他是一种价值观,并不是规则
- "我刚刚做的事情,让整个系统更容易改变,还是更难改变"
- DRY:不要重复
- 不要依赖你无法控制的东西
- 改变某对象的状态,让他自己来完成
- 可逆性:不要只有一个想法
- 不要追求
时髦 - 学习另一门语言(C/YALM/Python)
- 使用
曳光弹完成项目 - 最好使用内部语言测试
第三章 基础工具
学习一门文本处理/辅助语言
- 就决定是你了,Python!!!!
第四章 务实的偏执
DBC(契约式编程)
- 前置条件:传递良好的数据/前置环境,是调用者的责任,前置条件不匹配,抛出异常(语言不支持的话,只能在用例里手动assert触发)
- 后置条件:履行的职责结果保证为真,结果是准确的
- 类的不变式:精准的前置条件访问权限
- 简短的代码块,职责少的代码块
尽早崩溃
- 不要捕获一个函数所有异常,然后再抛出去,没有任何意义
- 因为异常随时新增,捕获不全,有异常的程序并不会让程序黯然失色
- 防御式编程是在浪费时间,让他崩溃!
- 统一提供监管去处理异常是优秀的设计
- 死掉的程序比瘫痪的程序损失要小得多
- 不要彻底的关闭断言
资源平衡
- 释放资源的顺序要与分配资源的顺序相反
- 在多处代码块申请不同资源的时候,申请资源顺序要保持一致
- 以上是运行时的资源问题,非运行时资源,譬如说日志,统计,是否滚动日志同时做了清理
- 随时提醒自己,是否有资源还未考虑到
- 技巧:当异常处理会影响到资源管理时,把资源管理嵌入到
类里,这种情况,会有特别的好处 - 处理异常资源释放的正确姿势
thing = allocate_resourece()
negin
process(thing)
finally
deallocate(thing)
end
- 无法保证平衡时(上述平衡将不能保证)
- 原因:动态类型的程序,分配一个内存,并且把此数据交给更大结构中
- 处理方案大约有三种:
- 顶层负责释放它所包含的所有子结构,然后将这些结构递归的删除包含他们的子数据等
- 顶层结构只做简单的释放,他所指向的每个结构,都变得无处引用
- 如果包含子结构,则顶层拒绝释放自己
不要冲出前灯
- 小步前进-有始至终
- 深思熟虑的小步骤,同时检查反馈,不断推进调整
- 什么是大步骤
- 我们只能看到两小时,最多两三天,超过则不能
- 预估未来几个月的之后的完成日期
- 为将来的维护和可拓展做预设(适可而止,把当前代码做成可替换的,将来更有效)
- 猜测用户将来有什么需求
- 猜测将来有什么技术可用
第五章 宁弯不折
编写更少的代码,配置将细节移除代码
解耦
- 耦合的症状:
- 不相关的库和模块,发生古怪的依赖关系
- 对一个模块简单的修改,会传播到其他系统模块,或者会破坏掉他们
- 开发人员会害怕修改代码,因为他们不确定会造成什么影响
- 铁道事故(链式的调用)
- 譬如这样,只要有任何一个地方需求改变,拓展将变得复杂繁琐
public void applyDiscount(customer, order_id, discount){ customer .orders .find(order_id) .getTotal() .applyDiscount(discount); } - 正确做法
- 只管命令,不要询问
- 不要根据对象的状态,去做决策,然后更新它(这也是不会划分职责的重要原因)
public void applyDiscount(customer, order_id, discount){ customer .findOrder(order_id) .applyDiscount(discount); } - 例外
- 语言提供的库非常稳定,可以使用
- 譬如这样,只要有任何一个地方需求改变,拓展将变得复杂繁琐
- 邪恶的全局化
- 尽可能避免全局化,只提醒一点
- 如果非要全局化,包装一层吧
响应式程序
- 事件
- 有限状态机
- 不要惧怕他,他只是工作流的一种控制方式
- 当非常适合状态切换的时候,使用它
- 把状态保存在外部储存器中,并使用状态来驱动流程迭代
- 缺点
- 并不能解决任何问题
- 观察者模式
- 声明函数注册列表在被观察者处,外部注册,行为产生式调用注册函数
- 缺点
- 注册的函数列表和被观察者在一处,产生依赖
- 事件的抛出式同步的,容易产生性能瓶颈(订阅/发布解决此问题)
- 订阅/发布
- 有
发布者与订阅者,两者是通过信道通信,不管内部实现方式,解耦,提升效率
- 有
- 响应式编程/流与事件
- 通过流来分析事件,可以理解为是一种思想
- 例如:双击事件,250ms内每点一次写进流,250ms过后把流打包,传输给订阅者,订阅者解析是否有两次点击,触发双击事件
- 因为是流,所以异步
- 变换式编程(管道)
- 完成一个目的,输入到输出通过一些流程进行转换,得到最终结果
- 这种思想是优秀的
- 在OO思想里,InputStream变换比较像
- 不要囤积状态,传递下去
- 错误处理:
- 永远不要在变换之间传递原始值,因为这样你无法验证有效性,取而代之的是封装在一个结构里,传递下去,验证有效性
- 首先选择一个表达式(如Elixir语言的:{:ok, value},{:error, reasion})
- 在变换函数内部处理,通过元组的第一个参数是否是ok,来执行不同版本的函数,把结果添加到元组里返回元组
- 加强版:包装一个执行函数,取出结果ok才执行下一个
- 在平时工作中使用这种思想,代码会越来越简洁
- 有限状态机
- 继承税(不要扛着大山去兜风)
- 接口
- 委托
- 拓展方法(mixin)
- 譬如拓展接口是个不错的选择
- 用以上方式代替继承
- 配置
- 一个比较优秀的方案是:把配置做成一个服务,通过服务的api去查询配置,不要写成全局变量
- 当决策出现两个方案的时候,不要懒惰的做成配置方案,决策出来,选择一个
第六章 并发
打破时域耦合
- 定义
- 依赖时间
- 依赖调用顺序('滴滴'必须在'哒哒'之后执行)
PS:欢迎评论(。^▽^)
浙公网安备 33010602011771号