对面向对象与设计模式的看法

前言

写这篇日记的时候楼下的邻居正在装修,沪漂小伙苦不堪言。回想起之前朋友和我抱怨去杭州面试那里的面试官喜欢扣设计模式细节,和我自己3月亲身去重庆面试的经历,我发现很多的面试官真的很问这个并且抠细节,然而他们自己连面向对象是什么都很模糊。为问而问,为用而用,大可不必。

设计模式很重要

我写它的目的不是想证明设计模式不重要,也不是为了批判现在的航母面试。相反我是想佐证设计模式的重要性,但是在我们能真正有资格谈论设计模式前我们至少先对面向对象编程有个清晰的认知,对为什么设计出设计模式和设计的目的有个数。

面向对象

面向对象分为面向对象语言面向对象风格,我们常见的 PHP JAVA Go 等都是面向对象的语言,而 C Js 则不是面向对象语言。面向对象语言面向对象风格的区别是什么呢?

简单来说面向对象需要语言层提供下面的一些特性

面向对象语言的特性

继承

把可以复用的代码抽取出来放到父类提供复用,避免重复的写相同的代码,但是它也经常被诟病。深层级的继承会影响可测试性和可读性。由此产生了多组合少继承的说法,GO就是基于组合的设计思路。

封装

提供了信息隐藏和数据保护,我们只暴露出需要让调用方知道和修改的属性或者方法。

抽象

隐藏内部实现细节,调用方只需要知道调用一个方法是干什么的,而不需要明白是怎么做到的。常见的interfaceabstract是抽象实现的特性,而函数其实也是一种抽象

多态

可以用子类替换父类并可以调用子类的方法。

  • 支持父类对象引用子类对象
  • 支持继承
  • 支持子类重写父类

区别

面向对象语言 从语言层面支持了上述的特性,但是并不是支持了这些特性的语言就是面向对象编程的,因为它的特性可能被人为的破坏掉。
面向对象风格 是指的用面向过程的语言经过巧妙的设计也可以实现出面向对象语言所提供的特性

代码质量

面向过程编程和面向对象编程其实没有谁优于谁的说法,都是时代的产物。在代码量不多的场景下面向过程更适合阅读也可以更快的开发,在大型需要多人协作的场景下面向对象更适合。我们编写代码的时候需要考虑以下的一些衡量代码质量的标准。

可维护性

在不破话原有代码设计不引入新bug的情况下能快速修改或添加代码

可读性

任何人都可以编写计算机能理解的代码,而好的程序员能编写人能理解的代码。这是一个综合的评判比如良好的英文命名风格,模块设计等等。

可扩展性

不修改或者少量修改原有代码的情况下通过扩展的方式添加新的功能

灵活性

预留一定的扩展点,有足够的底层可复用抽象模块

简洁性

尽量保证代码简单减少不必要的炫技行为

可复用性

尽量减少重复代码的编写,复用以后代码

可测试性

可测试性侧面反映了代码质量的高低,比如我前面说到的go单元测试

设计模式的设计原则

设计模式其实只是一些具体的落地措施,实际上的一些设计思想前辈们是总结出了很多原则和套路的,最常见的有下面这些

单一职责

一个类或者模块只负责完成一个职责或者功能

里式代换

子类对象可以在任何地方替换父类对象

开放闭合

对扩展开放,对修改闭合

依赖反转

高层级模块不依赖低层级模块,应该通过抽象相互依赖,抽象不依赖细节,细节依赖抽象。实现依赖反转的场景方法有下面两个

控制反转(IOC)

指的把原来由程序控制的流程反转给了框架,类似Laravel我们只需要根据框架定义好的扩展点去写代码,流程会被框架以list的形式放着一起,一般还会暴露一些操作list的方法。如Laravel的服务提供者就是会把一系列相关的服务放到一个继承了同一个父类的list中暴露出了抽象方法。

依赖注入

在类中去实例化一个对象会造成类与类之间的耦合,这是违反我们设计原则的。依赖注入解决了类与类之间的依赖关系。由外部传入实例好的类对象,是一种基于接口编程的体现。同时依赖注入也为我们写单元测试mock提供了便利。

KISS

Keep It Simple and Stupid.
Keep It Short and Simple.
Keep It Simple and Straightforward
尽量保持简单

YAGNI

You Ain’t Gonna Need It。
不要设计当前用不到的功能

DRY

Don’t Repeat Yourself
不要编写重复代码

LoD

迪米特,高内聚低耦合,
高内聚 类本身的设计,相近的设计尽量放到同一个类中
低耦合 类之间的依赖关系要尽量的简单单一
每个模块只应该了解那些与它关系密切的模块(最少知道原则)

总结

学习坡度

学习设计模式是很有必要的,但是在这之前我们应该知道设计模式的由来,学习的路径建议是

了解面向对象 -> 读懂设计原则 -> 熟悉设计模式

而不是一味的去扣一些设计模式写法上面的细节

带着目的

要搞懂我们为什么要花这些时间去投资学习这些方法论,我的目的是

  1. 能更顺利的读懂框架源码,(Laravel我还想带入设计模式看一遍文档)了解设计思路
  2. 写出高质量的代码
  • 版权声明: 本博客所有文章除特别声明外,著作权归作者所有。转载请注明出处!

请我喝杯咖啡吧~