《设计模式之美》 - 王铮

一、代码质量

第2篇. 如何评价代码质量的高低?

有如下几个最常用的、最重要的评价标准。

1) 可维护性(maintainability)。如果bug容易修复,修改、添加功能能够轻松完成,可以主观地主为代码可维护性佳。

2)可读性(readability)。我们需要看代码是否符合编码规范、命名是否达意、注释是否详尽、函数是否长短合适、模块划分是否清晰、是否符合高内聚低耦合等等。

3)可扩展性(extensibility)。代码预留了一些功能扩展点,你可以把新功能代码,直接插到扩展点上,而不需要因为要添加一个功能而大动干戈,改动大量的原始代码。

4)灵活性(flexibility)。如果一段代码易扩展、易复用或者易用,我们都可以称这段代码写得比较灵活。

5)简洁性(simplicity)。

6)可复用性(reusability)。

7)可测试性(testability)。代码可测试性差,比较难写单元测试,那基本就能说明代码设计得有问题。

要写出满足评价标准的高质量代码,我们需要掌握一些更加细化、更加能落地的编程方法论,包括面向对象设计思想、设计原则、设计模式、编码规范、重构技巧等。而所有这些编程方法论的最终目的都是为了编写出高质量的代码。

二、面向对象

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

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

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

3)设计模式是针对软件开发中经常遇到的一些设计问题,总结出来的一套解决方案或者设计思路。应用设计模式的主要目的是提高代码的可扩展性。

4)编程规范主要解决的是代码的可读性问题。持续小重构依赖的理论基础主要是编程规范。

5)重构作为保持代码质量不下降的有效手段,利用的就是面向对象、设计原则、设计模式、编码规范这些理论。

第4-10篇:面向对象

  1. 面向对象语言的特点:封装、抽象、继承、多态。分别可以解决哪些问题呢?
  2. 封装:类通过暴露有限的访问接口,授权外部仅能通过类提供的函数来访问内部信息或数据。封装将数据和方法绑定在一起,通过访问权限控制,只允许外部调用者通过类暴露的有限方法访问数据,提高了代码的可读性、可维护性和易用性。
  3. 抽象:让调用者只需要关心方法提供了哪些功能,并不需要知道这些功能如何实现。java中借助接口类或抽象类这两种语法机制,来实现抽象这一特性。函数本身也是抽象的一种体现。
  4. 继承:继承用来表示类之间的is-a关系。继承最大的好处是代码复用。但过度使用继承,继承层次过深过复杂,就会导致代码可读性、可维护性变差。继承特性是面向对象编程所特有的两个特性之一,另一个是多态。
  5. 多态:多态是指子类可以替换父类,在实际的代码运行过程中调用子类的方法实现,遵从了“对修改关闭、对扩展开放”的设计原则,提高了代码的扩展性和复用性。
  6.  滥用getter setter方法,破坏类了封装性;滥用全局变量和全局方法;定义数据和方法分离的类 等行为均会破坏面向对象特性。
  7. 在面向对象编程中,抽象类和接口是两个经常被用到的语法概念,是面向对象四大特性,以及很多设计模式、设计思想、设计原则编程实现的基础。java8中,接口中可以定义默认方法(default)和类方法(static)。接口和抽象类的区别。抽象类需要被继承,与子类是is-a的关系。接口类需要被实现,一个类可以同时实现多个接口,表示一种has-a的关系。抽象类更多的是为了代码复用,而接口就更侧重于解耦。接口是对行为的一种抽象,相当于一组协议或者契约,调用者可需要关注抽象的接口,不需要了解具体实现。接口实现了约定和实现相分离,可以降低代码间的耦合性,提高代码的可扩展性。怎么决定是使用接口还是抽象类呢?如果是is-a关系,并且是为了解决代码复用问题,我们就用抽象类;如果是一种has-a关系,并且是为了解决抽象而非代码复用,我们就可以使用接口。另外,抽象类是一种自下而上的设计思路,先有子类的代码重复,然后再抽象成上层的父类。而接口正好相反,是一种自上而下的设计思路,一般是先设计接口,再考虑具体实现。
  8. 应基于抽象而非实现编程。应用这条原则,可以将接口和实现相分离,封装不稳定的实现,暴露稳定的接口。上游系统面向接口而非实现编程,不依赖不稳定的实现细节,这样当实现发生变化时,上游系统的代码基本上不需要做改动,以此来降低耦合性,提高扩展性。越抽象、越顶层、越脱离具体某一实现的设计,越能提高代码的灵活性,越能应对未来的需求变化。好的代码设计,不仅能应对当下的需求,而且在将来需求变化的时候,仍然能够在不破坏原有代码设计的情况下灵活应对。在做软件开发的时候,一定要有抽象意识、封装意识、接口意识。在定义接口的时候,不要暴露任何实现细节。接口的定义只表明做什么,而不是怎么做。而且,在设计接口的时候,我们要多思考一下,这样的接口设计是否足够通用,是否能够做到替换具体的接口实现的时候,不需要任何接口定义的改动。
  9. 如果在我们的业务场景中,某个功能只有一种实现方式,未来也不可能被其他实现方式替换,那我们就没有必要为其设计接口,也没有必要基于接口编程,直接使用实现类就可以了。
  10. 组合优于继承,多用组合少用继承。继承用来表示类之间的is-a关系,可以解决代码复用的问题。虽然继承有诸多作用,但继承层次过深、过复杂,也会影响到代码的可维护性。类的继承层次会越来越深、继承关系会越来越复杂。而这种层次很深、很复杂的继承关系,一方面会导致代码的可读性变差。因为我们要搞清楚某个类具有哪些方法、属性,必须阅读父类的代码、父类的父类的代码,一直追溯到最顶层父类代码。另一方面这也破坏了类的封装特性,将父类的实现细节暴露给了子类。子类的实际依赖父类实现,两者高度耦合,一旦父类代码修改,就会影响所有子类的逻辑。我们可以利用组合、接口、委托三个技术手段,一块我来解决继承存在的问题。从理论上讲,通过组合、接口、委托三个技术手段,我们完全可以替换掉继承,在项目中不用或者少用继承关系,特别是一些复杂的继承关系。
  11. 如果类之间的继承结构稳定,不会轻易改变,继承层次比较浅(比如,最多有两层继承关系),继承关系不复杂,我们就可以大胆地使用继承。反之,系统越不稳定,继承层次很深,继承关系复杂,我们就尽量使用组合来替代继承。

三、设计原则

四、编码规范

五、重构技巧  

posted @ 2020-10-09 13:45  myLittleGarden  阅读(1434)  评论(0)    收藏  举报