从本周起,笔者将会就详细阐述面向对象的五大基本原则,分别是:
- 单一职责原则
- 开闭原则
- 里氏替换原则
- 依赖倒转原则
- 接口隔离原则
在开始每周讲一个具体的原则前,本周笔者希望写一篇序章,解释下为什么笔者认为这些基本的原则才是最基本的,同时也是最重要的
一)没有经历则很难理解
事实上,笔者认为,如果不是亲身编写过很多年的代码,使用过种类繁多的编程语言,大多数程序员是很难真正意识到这些原则的重要性。
这几个原则是Robert.C Martin在其架构整洁之道一书中提出来的,事实上,在笔者的印象中,笔者差不多工作几年的时候就已经从一些书上看过对类似原则的讲解。但笔者可以肯定的是,至少那个时候笔者的感悟与现在不可同日而语。
为什么笔者在现在会如此重视这些原则呢?
根本原因在于笔者自身的编程经历,笔者是一个『非主流程序员』
什么叫主流程序员?大多数程序员的编程的职业经历都属于技术方向非常固定且单一的,如果你从一开始从事后端,比如Java的话,那很可能你整个职业生涯都是在后端中,唯一有改变的是普通到高级,再到架构师,或许再往上技术总监等,也有可能你会从Java换成Kotlin等其它后端开发语言,但一个后端人员从事移动端或前端技术方向的开发,这个是极其少见的事情。
与之同理,我们以同样的角度来衡量移动端或前端的程序员时,他们同样有这样的职业体验。
事实上,大多数主流程序员都是这个模式,笔者称这种模式为:主流程序员
而笔者由于自身的一些非常偶然的原因,在做了几年Java,成了一个架构师之后,突然又使用了Java语言去搞了Android开发一段时间,而后又使用OC语言主导了iOS移动开发工作。又在2020年的时候,基于TypeScript React做了一个基于Electron桌面开发,在21年初的时候在了解响应式编程的过程中,发现了Vert.x与Kotlin,于是在今年的一个项目中,未有使用自己熟悉的Java语言,而是转而重头开始基于Kotlin与Vert.x构建一个全新的编程模式。
这就是非主流的原因,事实上,笔者认为很难有多少程序员在职业生涯中能有这样的经历。
或许有些人会认为这样的杂而不精,但事实上这也是笔者想要阐述面向对象五大基本原则的原因所在,因为据笔者感觉,自己并未出现杂而不精的现象。
因为:
所有面向对象的编程语言本质上都是一样的
你可以发现,面向对象的五大基本原则 ,对于任何一种面向对象的语言来说,都是成立的。
再往上一层,你又会发现,常用的设计模式,类似单例,工厂,观察者,命令模式等七七八八的,同样对所有面向对象的语言都是成立的。
再往上,一些思想,如果MVC,MVVP,领域驱动,分层等,也是一样适应用所有面向对象的语言
再往上,重构,测试驱动 (TDD),自动构建,敏捷软件开发这些优秀的编程实践或理念,同样适用于任何一种面向对象的语言
二)把技术及语言当成工具与手段
这就是笔者想要说的一个最重要观点:把技术或语言,当成工具与手段
笔者做为技术人员,也非常清楚很多技术人员心中有强烈的技术情节,表现为对特定技术模式的喜爱或是编程模式的追求。
事实上,我们可以把编程这个事情想象成画画或写作。
画画的目标是画出一幅画,至于使用的画笔是什么,画纸是什么,这应该是依据你要画的东西来决定,也就是画家需要一掌握一套工具集,一系列的工具,当需要什么的时候,他就得用什么
写作也是非常类似的,写作的手法有非常多种,你想表达什么才是最关键的,用最合适的文笔来达到你想要表达的目标。
那编程,本质上也是类似的工作,做为一个程序员,没有必要把自己限定为在某个特定的语言或技术方向。比如限制自己只能使用Java,非Java的我搞不来,还有后端程序员最喜欢说的:前端我搞不来。(事实上,前端这些年的技术发展可以用质变来形容,已经完全变成一个可以用面向对象的思维来写前端了)
这些都是作茧自缚的表现,也是我们程序员必须要避免的一个事情。
所以,笔者认为一个合格的程序员,不能只会或只使用一种语言,事实上,就笔者看到的国外的优秀的程序员来说,都基本是会使用各式各样的语言,甚至一些学习曲线比较高的非现代语言。
三)决定编码能力的是道,而非术
笔者曾在20年在公司做过一次培训,主题是:编码的道与术
阐述的是笔者对编程的一个重要的价值观:编码的能力,根本在于道,而非术
什么是道,什么是术?
由于本篇不是讲这个的,笔者就简单论述下笔者的理解。
术
我们使用的各式各样的语言,框架,类库,这些具体的玩意,统称为术。比如前端的技术人员,JavaScript,TypeScript,React,Vue,WebPack等等,后端的Java,Spring,JPA,Hibernate,Mysql等等,这些为术。
术是具体的,容易变化的,也不可能是决定因素。
不可能存在一个人说他用Java写出好的东西,用Kotlin就写不出,同样不可能出现用React就能写出好的代码,而VUE则不行的现象。
道
而与之相对就的,笔者在前文所说的
- 面向对象的基本原则
- 设计模式
- 架构风格或模式:分层,领域驱动,六边型,事件源等
- 思想:敏捷软件开发,TDD驱动思想等
- 重构,代码简洁之道,架构整洁之道等
这些为道,很显然,这些才是决定一个人是否是优秀的程序员,一个人是否能写出好的代码与关键所在。
老子几千年前就说过:
道生一,一生二,二生三,三生万物
如果你能理解这句话,就能理解编程的最重要的是什么了
四)会杂而不精么
很多程序员的一个担忧是:会不会杂而不精
这个担忧的原因本质还是在于包括程序员自己,以及评价程序员的整套社会标准体系,仍然处于对术的追求上,当我们使用多少年的Java的经历时,会被认可为高级程序员或架构师。所以如今的技术面试基本是对特定语言或技术框架的考核上。
笔者相信,没有多少公司或掌握决策权的人,会让一个在后端工作很多年的程序员去写前端。因为我们的评价体系认为,这个程序员并不掌握前端知识,肯定不如招一个在前端编写了很多年经验的程序员靠谱。
这确实是一个存在的社会现实,也是当前难以改变的。但笔者至少从自身的经验上来说,这个现象是不成立的。
当你掌握了编程的道时,掌握了类似面向对象的基本原则,设计模式,架构风格与模式,重构,TDD等这些道时,我很难想像这样的人会写不好一个Android客户端,或是写不出一个优秀的桌面客户端,就因为他从来没有写过,或说没有这方面的经验?
这些使用的语言全是面向对象的语言,你在后端能用得上的那些设计模式与理念,在移动端或前端上一样能用得上。
能在后端写出优雅简洁的代码,而又在前端写出垃圾代码,就因为没写过前端,没用过前端的编程语言?这种事显然是不存在的。
而且退一万步说,基于环境的限制或个人选择,就算你决定只用一种语言,只追求一个方向,那决定你是否是一个优秀的编程人员的本质仍然不在于你工作了多少年,或使用某个特定的语言,框架多少年,里面各种七七八八的功能特性你都清楚多少或用过多少。而仍然在于你对编程之道的理解与掌握上。
这也是为什么Rober C.Martin的书是这样的
- 代码整洁之道
- 架构整洁之道
- 程序员的职业素养
- 敏捷软件的原则与实践
- 敏捷整洁之道
看到没?没有C 编码之道,Java从入门到精通,30天学会React这样的书。
当然,笔者不是说术不重要,当然它也很重要,但它不是根本。也不占决定因素。
五)做优秀的程序员
未来的时代,程序只会越来越多,越来越重要,这会需要越来越多的程序员,这仍然有赖于我们这个群体的努力。
如同作家用文字写出好的书或作品,画家用画笔画出美的东西,音乐家用音符谱写出动听的音乐一样,我们则是用代码构建更好的产品与服务,服务于更多的人。
因此,写代码的你需要理解与明白,你怎么样才能写出好的代码,才能提升自己的能力。事实上,若不是许多年前有人指出我的代码完全是面向过程,没有美感可言,相信我也难以走到今日之地步。
这也是我写这篇文章的原因所在。
以此为序。