前⾔

什么是设计模式

设计模式讲的是如何写出可扩展、可读、可维护的⾼质量代码,所以,它们跟平时的编码会有直接的关系,也会直接影响到你的开发能⼒。

为什么要学习设计模式

  1. 应对⾯试中的设计模式相关问题。
  2. 告别写被⼈吐槽的烂代码。我⻅过太多的烂代码,⽐如命名不规范、类设计不合理、分层不清晰、没有模块化概念、代码结构混乱、⾼度耦合等等。这样的代码维护起来⾮常费劲,添加或者修改⼀个功能,常常会牵⼀发⽽动全身,让你⽆从下⼿,恨不得将全部的代码删掉重写!
  3. 提⾼复杂代码的设计和开发能⼒。
  4. 让读源码、学框架事半功倍。
  5. 为你的职场发展做铺垫

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

仔细看前⾯罗列的所有代码质量评价标准,你会发现,有些词语过于笼统、抽象,⽐较偏向对于整体的描述,⽐如优雅、好、坏、整洁、清晰等;有些过于细节、偏重⽅法论,⽐如模块化、⾼内聚低耦合、⽂档详尽、分层清晰等;有些可能并不仅仅局限于编码,跟架构设计等也有关系,⽐如可伸缩性、可⽤性、稳定性等。

为了做到有的放⽮、有重点地学习,我挑选了其中⼏个最常⽤的、最重要的评价标准,来详细讲解,其中就包括:可维护性、可读性、可扩展性、灵活性、简洁性(简单、复杂)、可复⽤性、可测试性。接下来,我们逐⼀讲解⼀下。
代码质量的评价有很强的主观性,描述代码质量的词汇也有很多,⽐如可读性、可维护性、灵活、优雅、简洁等,这些词汇是从不同的维度去评价代码质量的。它们之间有互相作⽤,并不是ᇿ⽴的,⽐如,代码的可读性好、可扩展性好就意味着代码的可维护性好。代码质量⾼低是⼀个综合各种因素得到的结论。我们并不能通过单⼀的维度去评价⼀段代码的好坏。

  1. 可维护性maintainability),落实到编码开发,所谓的“维护”⽆外乎就是修改 bug、修改⽼的代码、添加新的代码之类的⼯作。所谓“代码易维护”就是指,在不破坏原有代码设计、不引⼊新的 bug 的情况下,能够快速地修改或者添加代码。所谓“代码不易维护”就是指,修改或者添加代码需要冒着极⼤的引⼊新 bug 的⻛险,并且需要花费很⻓的时间才能完成。
  2. 可读性readability),我们在编写代码的时候,时刻要考虑到代码是否易读、易理解。除此之外,代码的可读性在⾮常⼤程度上会影响代码的可维护性。毕竟,不管是修改 bug,还是修改添加功能代码,我们⾸先要做的事情就是读懂代码。代码读不⼤懂,就很有可能因为考虑不周全,⽽引⼊新的 bug。我们需要看代码是否符合编码规范、命名是否达意、注释是否详尽、函数是否⻓短合适、模块划分是否清晰、是否符合⾼内聚低耦合等等。你应该也能感觉到,从正⾯上,我们很难给出⼀个覆盖所有评价指标的列表。这也是我们⽆法量化可读性的原因。
  3. 可扩展性extensibility),代码的可扩展性表示,我们在不修改或少量修改原有代码的情况下,通过扩展的⽅式添加新的功能代码。说直⽩点就是,代码预留了⼀些功能扩展点,你可以把新功能代码,直接插到扩展点上,⽽不需要因为要添加⼀个功能⽽⼤动⼲⼽,改动⼤量的原始代码。
  4. 灵活性flexibility),从刚刚举的场景来看,如果⼀段代码易扩展、易复⽤或者易⽤,我们都可以称这段代码写得⽐较灵活。所以,灵活这个词的含义⾮常宽泛,很多场景下都可以使⽤。
  5. 简洁性simplicity),有⼀条⾮常著名的设计原则,你⼀定听过,那就是 KISS 原则:“Keep It Simple,Stupid”。这个原则说的意思就是,尽量保持代码简单。代码简单、逻辑清晰,也就意味着易读、易维护。我们在编写代码的时候,往往也会把简单、清晰放到⾸位。不过,很多编程经验不⾜的程序员会觉得,简单的代码没有技术含量,喜欢在项⽬中引⼊⼀些复杂的设计模式,觉得这样才能体现⾃⼰的技术⽔平。实际上,思从深⽽⾏从简,真正的⾼⼿能云淡⻛轻地⽤最简单的⽅法解决最复杂的问题。这也是⼀个编程⽼⼿跟编程新⼿的本质区别之⼀。可复⽤性,代码的可复⽤性可以简单地理解为,尽量减少重复代码的编写,复⽤已有的代码。
  6. 可测试性,相对于前⾯六个评价标准,代码的可测试性是⼀个相对较少被提及,但⼜⾮常重要的代码质量评价标准。代码可测试性的好坏,能从侧⾯上⾮常准确地反应代码质量的好坏。代码的可测试性差,⽐较难写单元测试,那基本上就能说明代码设计得有问题。

最常⽤的评价标准有哪⼏个?

最常⽤到⼏个评判代码质量的标准是:可维护性、可读性、可扩展性、灵活性、简洁性、可复⽤性、可测试性。其中,可维护性、可读性、可扩展性⼜是提到最多的、最重要的三个评价标准。

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

  • ⾯向对象编程因为其具有丰富的特性(封装、抽象、继承、多态),可以实现很多复杂的设计思路,是很多设计原则、设计模式等编码实现的基础。
  • 设计原则是指导我们代码设计的⼀些经验总结,对于某些场景下,是否应该应⽤某种设计模式,具有指导意义。⽐如,“开闭原则”是很多设计模式(策略、模板等)的指导原则。
  • 设计模式是针对软件开发中经常遇到的⼀些设计问题,总结出来的⼀套解决⽅案或者设计思路。应⽤设计模式的主要⽬的是提⾼代码的可扩展性。从抽象程度上来讲,设计原则⽐设计模式更抽象。设计模式更加具体、更加可执⾏。
  • 编程规范主要解决的是代码的可读性问题。编码规范相对于设计原则、设计模式,更加具体、更加偏重代码细节、更加能落地。持续的⼩重构依赖的理论基础主要就是编程规范。
  • 重构作为保持代码质量不下降的有效⼿段,利⽤的就是⾯向对象、设计原则、设计模式、编码规范这些理论。

实际上,⾯向对象、设计原则、设计模式、编程规范、代码重构,这五者都是保持或者提⾼代码质量的⽅法论,本质上都是服务于编写⾼质量代码这⼀件事的。当我们追本逐源,看清这个本质之后,很多事情怎么做就清楚了,很多选择怎么选也清楚了。⽐如,在某个场景下,该不该⽤这个设计模式,那就看能不能提⾼代码的可扩展性;要不要重构,那就看重代码是否存在可读、可维护问题等。