设计模式之美导学

为什么要学习设计模式?

越早学习设计模式越好,有些东西早点知道,才能在日后一直发挥作用

在计算机五大件(计组, 计网, 操作系统, 编译原理, 设计模式)中

  • 数据结构和算法研究如何高效实现

  • 设计模式研究如何保证代码的可维护性

总结

  • 应对面试中的设计模式相关问题
  • 告别被别人吐槽的烂代码(talk is cheap, show me your code)
  • 提高复杂代码的设计和开发能力
  • 让读源码,学框架事半功倍
  • 为职场发展做铺垫

在日常开发中用过哪些设计模式?

使用代理模式进行共性话处理,比如AOP思想,将非业务功能和业务功能解耦

  • 事务的处理 @Translation
  • 系统间上下文的传递ThreadLocal+ restTemplate#intercept等等

使用工厂 + 策略

  • 不同优惠种类的计算
  • 定制化功能的解耦

观察者模式 : 这个模式的思想在很多中间件(mq, zookeeper, netty等等)可以看到银子

  • 通过领域事件解耦业务
  • 理解eventloop, epoll等等
  • 通过watch实现动态配置, HA等等

职责链模式: pipeline思想

  • filter
  • 理解netty中的各种handler

从哪些维度评价代码质量的好坏?如何具备写高质量代码的能力?

如何评价代码质量的高低?

代码质量高低的指标是从不同维度进行评价且具有很大的主观性

且指标之间并不独立,维度可能重合

而且评价很难量化,并非非黑即白

最常用的评价标准

  • 可维护性
  • 可读性
  • 可扩展性
  • 灵活性
  • 简介性
  • 可复用性
  • 可测试性

可维护性

维护代码事件远远大于编码时间

维护无外乎 修改bug, 修改老代码, 添加新代码

易维护是指在不破坏原有代码设计, 不引入新的bug的情况下, 能快速地修改或者添加代码

可维护性由人而定, 很主观

可读性

Google 内部甚至专门有个认证就叫作 Readability。只有拿到这个认证的工程师,才有资格在 code review 的时候,批准别人提交代码。

可见代码的可读性有多重要,毕竟,代码被阅读的次数远远超过被编写和执行的次数。

查看代码是否符合编码规范, 命名是否达意, 注释是否详尽, 函数是否长短合适, 模块划分是否清晰, 是否符合高内聚低耦合等等

code review是一个很好的测验代码可读性地手段. 如果同事可以轻松地读懂你写的代码,那说明你的代码可读性很好

可扩展性

代码是否易于扩展

代码预留一些功能扩展点,不会因为添加一个功能,改动大量的原始代码

“对修改关闭, 对扩展开放”

灵活性

很抽象,不好下定义

举例场景可以被称为 代码写的灵活

  • 添加新的功能时, 原有代码已经预留好了扩展点, 不需要修改原代码,只需要在扩展点添加新的代码即可(扩展性)
  • 实现一个功能,发现原有代码中,已经抽象出很多底层可复用的模块(可复用性)
  • 使用某组接口时,这组接口可以应对各种使用场景,满足不同的的需求.(易用)

简洁性

KISS原则 “Keep it Simple , Stupid”

编程经验不足的程序员喜欢在项目中引入一些复杂的设计模式,认为这样才能体现出技术水平

真正的高手能云淡风轻的用最简单的方式解决最复杂的问题

可复用性

尽量减少重复代码的编写,复用已有的代码

Don’t Reapeat your self

可测试性

代码可测试性差,比较难写单元测试,那基本说明代码设计有问题

如何写出高质量的代码?

如何写出易维护,易读, 易扩展,灵活, 简洁, 可复用, 可测试的代码?

需要掌握一些更加细化,更加能落地的编程方法论

面向对象的设计思想, 设计原则, 设计模式, 编码规范, 重构技巧

面向对象,设计原则, 设计模式,编程规范, 重构,这五者之间的关系?

极客时间 设计模式之美 大纲,学习框架

image-20230916090931099

面向对象

主流编程范式(面向过程, 面向对象, 函数式)中的主流.

面向对象具有丰富的特性(继承,封装.多态,抽象),可以实现很多复杂的设计思路,是很多设计原则,设计模式编码实现的基础

接下来需要掌握

  • 面向对象的四大特性 : 封装, 抽象, 继承, 多态
  • 面向对象编程与面向过程编程的区别和联系
  • 面向对象分析, 面向对象设计, 面向对象编程
  • 接口类和抽象类的区别以及各自的应用场景
  • 基于接口而非实现的编程设计思想
  • 多用组合少用继承的设计思想
  • 面向过程的贫血模式和面向对象的充血模型

设计原则

设计原则这里比较抽象,不能单纯的记忆,需要掌握其设计初衷,解决哪些编程问题,有那些应用场景

  • SOLD原则-SRP 单一职责原则
  • SOLD原则-OCP 开闭原则
  • SOLD原则-LSP 里式替换原则
  • SOLD原则-ISP接口隔离原则
  • SOLD原则-DIP依赖倒置原则
  • DRY原则, KISS原则, YAGNI原则, LOD法则

设计模式

设计模式相较设计原则没那么抽象,难点在原了解他们都能解决哪些问题, 掌握典型的应用场景, 冰冻的不过度应用

23种经典设计模式,随着语言的严谨,一些设计模式(Singleton)随之过时,甚至成了反模式,一些内置在编程语言中(比如Iterator), 另外还有一些新模式的诞生(Monostate)

学习设计模式要有侧重点,对常用的设计模式,我们要多花时间理解掌握,对于不常用的只需要稍微了解即可

创建型(5)

常用: 单例, 工厂模式(工厂方法和抽象工厂), 建造者模式

不常用: 原型模式

结构型(7)

常用: 代理模式, 桥接模式, 装饰器模式, 适配器模式

不常用: 门面模式, 组合模式, 享元模式

行为型(11)

常用: 观察者模式, 模板模式, 策略模式, 职责链模式,迭代器模式, 状态模式

不常用: 访问者模式, 备忘录模式, 命令模式, 解释器模式, 中介模式

编码规范

主要解决的是代码可读性问题,相对设计原则, 设计模式, 更加具体,更加片中代码细节

是最起码要掌握的

比如 : 给变量,类,函数命名, 如何写代码注释, 函数不宜过长, 参数不能过多

已经有很多经典书籍了,没时间,看20条也够用

编码规范没有单独作为一个模块来讲解,而是放到重构中,重构分为大重构和小重构,小重构利用的知识点基本上就是编码规范

代码重构

软件开发中,只要软件在不停的迭代,就没有一劳永逸的设计,随着需求的变化, 代码的不断堆砌,原有设计必然存在这样那样的问题,针对这些问题,我们需要进行代码重构,重构是软件开发中重要的一环, 持续重构是保证代码质量不下降的有效手段,能避免代码孵化到无可救药的地步

我们前面讲的面向对象, 设计原则, 设计模式 一个重要的应用场景就是在代码重构的时候, 虽然设计模式可以提高代码的可扩展性,但过度不恰当地使用,也会增加代码地复杂度, 影响代码地可读性, 开发初期特别必须, 我们不要过度设计,应用复杂地设计模式.而是当代码出现问题时,在针对问题进行重构,避免前期地过度设计

  • 重构地目的(why), 对象(what), 时机(when), 方法(how) ;
  • 保证重构不出错地技术手段, : 单元测试和代码的可测试性
  • 两种不同规模的重构: 大重构(大规模高层次) 和 小重构(小规模低层次)

五者间的联系

  • 面向对象丰富的特性(继承, 封装, 多态, 抽象)可以实现很多复杂的设计思路, 是很多设计原则, 设计模式等编码实现的基础

  • 设计原则是指导我们代码设计的一些经验总结, 对于某些场景下,是否应该应用某种设计模式,具有指导意义. 比如, "开闭原则"是很多设计模式(策略, 模板等)的指导原则

  • 设计模式是针对软件开发中经常遇到的设计问题,总结出来的一套解决方案或者设计思想, 主要目的是提高代码的可扩展性. 设计原则比设计模式更抽象, 设计模式更加具体,更加可执行

  • 编程方式主要解决的是代码的可读性问题. 它相较于设计原则, 设计模式,更加具体,更加偏重代码细节,更加能落地. 持续的小重构依赖的理论基础主要是编程规范

  • 重构作为保持代码质量不下降的有效手段,利用的激素hi面向对象, 设计原则,设计模式,编码规范这些理论

锐评

再好的理论,应用不到实际中也是白费,对于提升代码质量,最有效的是编码规范,其次才是设计原则,再次是代码重构, 最后才是面向对象和设计模式