3.16 设计模式速查(全课程出现的模式)

目录 · ← l29

3.16 设计模式速查(全课程出现的模式)

模式用途出现在
ADT / 封装分离使用与实现R10–R12
迭代器 Iterator顺序访问而不暴露内部表示R8、R12
工厂方法 Factory把创建逻辑与使用解耦(creator)R10
观察者 / 监听器 Listener事件源通知多个订阅者R20
回调 Callback把控制流的”下一步”作为参数传入R16、R20
不可变对象 Immutable免于别名 bug、天然线程安全R8、R21
组合模式 Composite用统一接口处理”单个”与”组合”R26
解释器 Interpreter递归数据类型 + 求值函数 = 小语言R26
访问者 Visitor不改数据类型就增加新操作R27
监视器 Monitor用锁把 ADT 变成线程安全的R23
生产者-消费者用阻塞队列解耦生产与消费速度R24
客户端/服务器通过网络通信的两个角色R25

3.17 一页纸复习:20 条黄金法则

  1. 先写规格,再写实现。 说不清”做什么”就不该开始写”怎么做”。
  2. 前置条件是调用者的义务,后置条件是实现者的义务。 不要搞反。
  3. 规格要声明式,不要操作式。
  4. 允许实现自由度:除非调用者真的依赖,否则不要规定唯一答案。
  5. null 赶出你的接口。
  6. 优先不可变;可变对象必须小心别名。
  7. 可变对象进出 ADT 都要防御性拷贝。
  8. final 只防重新赋值,不防内部可变。
  9. AF 和 RI 必须写成代码注释,否则它们不存在。
  10. 所有构造函数建立 RI,所有 mutator 保持 RI,所有 observer 假设 RI 成立。
  11. checkRep() 放在每个构造函数和 mutator 的末尾。
  12. equals 相等 ⟹ hashCode 相等hashCode 绝不能用可变字段。
  13. 可变类型用引用相等,不可变类型用值相等。
  14. 测试先写,测试要能失败,边界值优先。
  15. fail fast:错误越早暴露越便宜。
  16. DRY:重复的代码是未来 bug 的温床。
  17. 避免共享可变状态;做不到就用锁或消息传递保护它。
  18. 统一锁顺序以避免死锁。
  19. 并发正确性靠设计保证,不能靠测试碰运气。
  20. 代码是写给人读的——包括未来的你。