005 Why You Need To Learn Design Patterns

设计模式学习导读

[TOC]

为什么说每个程序员都要尽早地学习并掌握设计模式相关知识?

  1. 很多程序员都知道基础知识的重要性,觉得要夯实基础,才能走得更远,但:基础知识有哪些?基础要怎么样才算是“夯实”?如何将基础知识转化成开发“生产力”?
    • 基础一般有哪些?框架、语言都是变化的,“不变”的是基础,如:计算机组成原理、操作系统原理、编译原理、网络原理、算法与数据结构、设计模式…
    • “夯实”的基础是怎么定义的?用最简单的方式,能快速实现解决问题,并明白其“本质”、“原理”
    • 为什么需要学习这些基础?CURD 其实可能用不上,但这些基础其实在潜移默化的影响你的学习速度、提高你对技术的理解、编写程序的质量;其次,功利性的说就是“大厂面试,都注重基础和经验”
  2. 为什么学习“设计模式”?如果说前面的基础是让你学会如何写出高效的代码(内功心法),那“设计模式”更像是“屠龙记”(具体的武功招式)教你学会“如何写出高质量的代码”。
  3. 烂代码的特征:命名不规范,类设计不合理,分层不清晰,没有模块化,代码混乱,高度耦合,没有抽象,代码行数太长,逻辑结构太复杂,代码参数太多,参数没有做任何封装
  4. 如何设计一个通用的模块/架构,该从哪些方面去思考:
    • 如何分层、分模块?
    • 应该怎么划分类?
    • 每个类应该具有哪些属性、方法?
    • 怎么设计类之间的交互?该用继承还是组合?该使用接口还是抽象类?
    • 怎样做到解耦、高内聚低耦合?
    • 该用单例模式还是静态方法?
    • 用工厂模式创建对象还是直接 new 出来?
    • 如何避免引入设计模式提高扩展性的同时带来的降低可读性问题?……
  5. 关于看源码的一些思考和观点
    1. 看源码是为了看什么?优秀的开源项目、框架、中间件,代码量、类的个数都会比较多,类结构、类之间的关系极其复杂,常常调用来调用去。所以,为了保证代码的扩展性、灵活性、可维护性等,代码中会使用到很多设计模式、设计原则或者设计思想。我们可以从这些优秀的源码中去学习别人的编写规范、设计原则、设计思想、实现方案技巧等信息
    2. 看源码遇到的两类问题
      • 看不懂、看不下去:有一些人看源码的时候,经常会遇到看不懂、看不下去的问题。实际上,这个问题的原因很简单,那就是你积累的基本功还不够,你的能力还不足以看懂这些代码。不懂这些设计模式、原则、思想,在看代码的时候,你可能就会琢磨不透作者的设计思路,对于一些很明显的设计思路,你可能要花费很多时间才能参悟。事倍功半,持续得不到正反馈,就会让人倦怠。
      • 以为看懂,但不会用:你自己觉得看懂了,实际上,里面的精髓你并没有 get 到多少?这是一个隐藏的问题,自己可能都比较难发现。因为优秀的开源项目、框架、中间件,就像一个集各种高精尖技术在一起的战斗机。如果你想剖析它的原理、学习它的技术,而你没有积累深厚的基本功,就算把这台战斗机摆在你面前,你也不能完全参透它的精髓,只是了解个皮毛,看个热闹而已。
  6. 学好设计模式相关的知识,不仅能让你更轻松地读懂开源项目,还能更深入地参透里面的技术精髓,做到事半功倍。
  7. 内容中涉及的问题:如何设计一个餐厅系统、停车场系统、售票系统?(作者觉得这题目老套…,然而我却不懂)

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

如何评价代码质量的好坏,比如:是否符合编程规范?可读性是否强?是否易扩展?是否易维护?是否足够简单?但…什么才算是可读性好、易扩展、易维护、足够简单的“标准”

  1. 可维护性:一个项目的维护时间远远大于编写代码的时间,因此代码的可维护性格外重要。可维护性就是指:在不破坏原有代码设计、不引入新的bug的情况下,能够快速地修改或者添加代码。(事实上,当代码的可读性好、简洁、可扩展性好,就会使得代码的维护性更简单。即:代码分层清晰、模块化好、高内聚低耦合、基于接口而非实现编程的设计原则; 易维护性与项目代码量、业务复杂度、技术复杂度、文档全面、开发水平等因素有关)
  2. 可读性:软件设计大师 Martin Fowler 曾经说过:“Any fool can write code that a computer can understand. Good programmers write code that humans can understand.”翻译成中文就是:“任何傻瓜都会编写计算机能理解的代码。好的程序员能够编写人能够理解的代码”。个人认为可读性应该是最重要的,如果连让人读明白都不行,谈什么可维护?代码是否符合编码规范、命名是否达意、注释是否详尽、函数是否长短合适、模块划分是否清晰、是否符合高内聚低耦合
  3. 可扩展性:代码预留了一些功能扩展点,支持新加功能、用户自定义时能直接最小改动。开闭原则(OCP):“对修改关闭,对扩展开放”。“对修改关闭”是为了保证现有代码的稳定性,“对扩展开放”开放是为了应对变化
  4. 简洁性:KISS原则-“Keep It Simple,Keep It Stupid”,让代码保持简单、逻辑清晰,自然就意味着“可读性高、易维护”
  5. 可复用性:DRY原则-“Don’t Repeat Yourself”,尽量减少重复代码的编写,复用已有的代码。要么一起错,更容易暴露问题,要么一起对没有问题。
    • 面向对象中“继承、多态”存在的目的之一就是为了提高可复用性
    • “单一职责”的设计原则
    • 重构技巧:解耦(低耦合)、高内聚、模块化
  6. 可测试性:代码的可测试性差,比较难写单元测试,那基本上就能说明代码设计得有问题。可测试性对于代码重构时非常的重要

==思从深而行从简,真正的高手能云淡风轻地用最简单的方法解决最复杂的问题。==

03 | 面向对象、设计原则、设计模式、编程规范、重构,这五者有何关系?

  • 面向对象:是一种设计思想和开发方法,其核心就是“关注各个构件,提高构件的独立性,通过将其组合起来实现系统整体功能”。即:将系统抽象设计为众多的“独立性较高”的对象,对象包含不同的方法、属性。面向对象分析(OOA)、面向对象设计(OOD)、面向对象编程(OOP)

    • 面向对象编程(OOP):将程序定义为一个个独立性不同的类,通过类创建实例对象,实例对象之间的相互作用,构成实现了软件的功能(即:类是模板,实例对象是实际工作的人)。面向对象的四大特效:抽象、封装、继承、多态
    • 面向对象的四大特性:封装、抽象、继承、多态
    • 面向对象编程与面向过程编程的区别和联系
    • 面向对象分析、面向对象设计、面向对象编程
    • 接口和抽象类的区别以及各自的应用场景
    • 基于接口而非实现编程的设计思想
    • 多用组合少用继承的设计思想
    • 面向过程的贫血模型和面向对象的充血模型
  • 设计原则:是指导我们代码设计的一些经验总结

    • SOLID 原则 -SRP 单一职责原则
    • SOLID 原则 -OCP 开闭原则
    • SOLID 原则 -LSP 里式替换原则
    • SOLID 原则 -ISP 接口隔离原则
    • SOLID 原则 -DIP 依赖倒置原则
    • DRY 原则、KISS 原则、YAGNI 原则、LOD 法则
  • 设计模式:设计模式是针对软件开发中经常遇到的一些设计问题,总结出来的一套解决方案或者设计思路。

    • ==设计原则是经验总结、是心法口诀==
    • ==设计模式是对设计原则的“最佳实践和扩展”==。因此:设计模式并非是一成不变的,随着语言的演进,一些设计模式(如:Singleton)也随之过时甚至是反例模式,本身设计模式在最初也是为了解决某些语言在语法特性上的局限性而诞生的最佳实践方案。

    设计模式分类:创建型、结构型、行为型 23种设计模式的UML图

    • 创建型:
      • 常用的有:单例模式、工厂模式(工厂方法或抽象工厂)、建造者模式
      • 不常用的:原型模式
    • 结构型:
      • 常用的有:代理模式、桥接模式、装饰者模式、适配器模式、门面模式(作者归位不常用,但很多类库都有用,如:ORM框架、写日志框架)
      • 不常用的:组合模式、享元模式
    • 行为型:
      • 常用的有:观察者模式、模板模式、策略模式、职责链模式、迭代器模式、状态模式
      • 不常用的:访问者模式、备忘录模式、命令模式、解释器模式、中介模式
  • 编程规范:主要解决的是代码的可读性问题,提供一些细节上的约束从而形成“共识”,减少大家的无效沟通交流。可以看:《重构》、《代码大全》、《代码整洁之道》

  • 代码重构:没有一劳永逸的设计,只有持续迭代变化的需求。随着需求的变化,原有的设计必定存在一些问题,此时针对这些问题就需要对代码进行重构。持续重构是保持代码质量不下降的有效手段,能有效避免代码腐化到无可救药的地步。重构代码之前需要知道:

    • 重构的目的(why)、对象(what)、时机(when)、方法(how)
    • 保证重构不出错的技术手段:单元测试(TDD)和代码可测试性
    • 不同规模的重构:大重构(大规模高层次)和小重构(小规模低层次)。大重构往往是一个漫长而新旧不断交替的痛苦过程,因此可测试性显得格外重要。

img

  • “设计原则”提供了心法口诀

  • 设计模式对这些心法口诀进行了具象化,成为了一门门具体的“内功秘籍”
  • 面向对象是修炼这些武功秘籍的“基础、丹药、武器、工具”
  • 编程规范是你练好这些武功的注意事项,避免走火入魔
  • “重构”是利用上述提到的东西,反复不断的“锤炼”

转载请声明出处: MinsonLee的博客:https://minsonlee.github.io

扫描下方二维码,关注公众号,接收更多实时内容

新猿呓码

打赏一个呗

取消

感谢客官打赏,您的打赏使我动力十足!

扫码支持
扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦