CategoryResourceRepost/极客时间专栏/设计模式之美/设计原则与思想:面向对象/04 | 理论一:当谈论面向对象的时候,我们到底在谈论什么?.md
louzefeng d3828a7aee mod
2024-07-11 05:50:32 +00:00

96 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<audio id="audio" title="04 | 理论一:当谈论面向对象的时候,我们到底在谈论什么?" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/e6/64/e6ae5e1b96d371ba3caa6f84c6d22764.mp3"></audio>
考虑到各个水平层次的同学,并且保证专栏内容的系统性、全面性,我会循序渐进地讲解跟设计模式相关的所有内容。所以,专栏正文的第一个模块,我会讲一些设计原则、设计思想,比如,面向对象设计思想、经典设计原则以及重构相关的知识,为之后学习设计模式做铺垫。
在第一个模块中,我们又首先会讲到面向对象相关的理论知识。提到面向对象,我相信很多人都不陌生,随口都可以说出面向对象的四大特性:封装、抽象、继承、多态。实际上,面向对象这个概念包含的内容还不止这些。所以,今天我打算花一节课的时间,先大概跟你聊一下,当我们谈论面向对象的时候,经常会谈到的一些概念和知识点,为学习后面的几节更加细化的内容做一个铺垫。
特别说明一下,对于今天讲到的概念和知识点,大部分我都是点到为止,并没有展开详细讲解。如果你看了之后,对某个概念和知识点还不是很清楚,那也没有关系。在后面的几节课中,我会花更多的篇幅,对今天讲到的每个概念和知识点,结合具体的例子,一一做详细的讲解。
## 什么是面向对象编程和面向对象编程语言?
面向对象编程的英文缩写是OOP全称是Object Oriented Programming。对应地面向对象编程语言的英文缩写是OOPL全称是Object Oriented Programming Language。
面向对象编程中有两个非常重要、非常基础的概念那就是类class和对象object。这两个概念最早出现在1960年在Simula这种编程语言中第一次使用。而面向对象编程这个概念第一次被使用是在Smalltalk这种编程语言中。Smalltalk被认为是第一个真正意义上的面向对象编程语言。
1980年左右C++的出现带动了面向对象编程的流行也使得面向对象编程被越来越多的人认可。直到今天如果不按照严格的定义来说大部分编程语言都是面向对象编程语言比如Java、C++、Go、Python、C#、Ruby、JavaScript、Objective-C、Scala、PHP、Perl等等。除此之外大部分程序员在开发项目的时候都是基于面向对象编程语言进行的面向对象编程。
以上是面向对象编程的大概发展历史。在刚刚的描述中,我着重提到了两个概念,面向对象编程和面向对象编程语言。那究竟什么是面向对象编程?什么语言才算是面向对象编程语言呢?如果非得给出一个定义的话,我觉得可以用下面两句话来概括。
- 面向对象编程是一种编程范式或编程风格。它以类或对象作为组织代码的基本单元,并将封装、抽象、继承、多态四个特性,作为代码设计和实现的基石 。
- 面向对象编程语言是支持类或对象的语法机制,并有现成的语法机制,能方便地实现面向对象编程四大特性(封装、抽象、继承、多态)的编程语言。
一般来讲, 面向对象编程都是通过使用面向对象编程语言来进行的但是不用面向对象编程语言我们照样可以进行面向对象编程。反过来讲即便我们使用面向对象编程语言写出来的代码也不一定是面向对象编程风格的也有可能是面向过程编程风格的。这里听起来是不是有点绕不过没关系我们在后面的第7节课中会详细讲解这个问题。
除此之外,从定义中,我们还可以发现,理解面向对象编程及面向对象编程语言两个概念,其中最关键的一点就是理解面向对象编程的四大特性。这四大特性分别是:封装、抽象、继承、多态。不过,关于面向对象编程的特性,也有另外一种说法,那就是只包含三大特性:封装、继承、多态,不包含抽象。为什么会有这种分歧呢?抽象为什么可以排除在面向对象编程特性之外呢?关于这个问题,在下一节课详细讲解这四大特性的时候,我还会再拿出来说一下。不过,话说回来,实际上,我们没必要纠结到底是四大特性还是三大特性,关键还是理解每种特性讲的是什么内容、存在的意义以及能解决什么问题。
而且在技术圈里封装、抽象、继承、多态也并不是固定地被叫作“四大特性”features也有人称它们为面向对象编程的四大概念concepts、四大基石cornerstones、四大基础fundamentals、四大支柱pillars等等。你也发现了吧叫法挺混乱的。不过叫什么并不重要。我们只需要知道这是前人进行面向对象编程过程中总结出来的、能让我们更容易地实现各种设计思路的几个编程套路这就够了。在之后的课程讲解中我统一把它们叫作“四大特性”。
## 如何判定某编程语言是否是面向对象编程语言?
如果你足够细心你可能已经留意到在我刚刚的讲解中我提到“如果不按照严格的定义来说大部分编程语言都是面向对象编程语言”。为什么要加上“如果不按照严格的定义”这个前提呢那是因为如果按照刚刚我们给出的严格的面向对象编程语言的定义前面提到的有些编程语言并不是严格意义上的面向对象编程语言比如JavaScript它不支持封装和继承特性按照严格的定义它不算是面向对象编程语言但在某种意义上它又可以算得上是一种面向对象编程语言。我为什么这么说呢到底该如何判断一个编程语言是否是面向对象编程语言呢
还记得我们前面给出的面向对象编程及面向对象编程语言的定义吗如果忘记了你可以先翻到上面回顾一下。不过我必须坦诚告诉你那个定义是我自己给出的。实际上对于什么是面向对象编程、什么是面向对象编程语言并没有一个官方的、统一的定义。而且从1960年也就是60年前面向对象编程诞生开始这两个概念就在不停地演化所以也无法给出一个明确的定义也没有必要给出一个明确定义。
实际上,面向对象编程从字面上,按照最简单、最原始的方式来理解,就是将对象或类作为代码组织的基本单元,来进行编程的一种编程范式或者编程风格,并不一定需要封装、抽象、继承、多态这四大特性的支持。但是,在进行面向对象编程的过程中,人们不停地总结发现,有了这四大特性,我们就能更容易地实现各种面向对象的代码设计思路。
比如我们在面向对象编程的过程中经常会遇到is-a这种类关系比如狗是一种动物而继承这个特性就能很好地支持这种is-a的代码设计思路并且解决代码复用的问题所以继承就成了面向对象编程的四大特性之一。但是随着编程语言的不断迭代、演化人们发现继承这种特性容易造成层次不清、代码混乱所以很多编程语言在设计的时候就开始摒弃继承特性比如Go语言。但是我们并不能因为它摒弃了继承特性就一刀切地认为它不是面向对象编程语言了。
实际上,我个人觉得,只要某种编程语言支持类或对象的语法概念,并且以此作为组织代码的基本单元,那就可以被粗略地认为它就是面向对象编程语言了。至于是否有现成的语法机制,完全地支持了面向对象编程的四大特性、是否对四大特性有所取舍和优化,可以不作为判定的标准。基于此,我们才有了前面的说法,**按照严格的定义,很多语言都不能算得上面向对象编程语言,但按照不严格的定义来讲,现在流行的大部分编程语言都是面向对象编程语言。**
所以,多说一句,关于这个问题,我们一定不要过于学院派,非要给面向对象编程、面向对象编程语言下个死定义,非得对某种语言是否是面向对象编程语言争个一清二白,这样做意义不大。
## 什么是面向对象分析和面向对象设计?
前面我们讲了面向对象编程OOP实际上跟面向对象编程经常放到一块儿来讲的还有另外两个概念那就是面向对象分析OOA和面向对象设计OOD。面向对象分析英文缩写是OOA全称是Object Oriented Analysis面向对象设计的英文缩写是OOD全称是Object Oriented Design。OOA、OOD、OOP三个连在一起就是面向对象分析、设计、编程实现正好是面向对象软件开发要经历的三个阶段。
关于什么是面向对象编程,我们前面已经讲过了。我们现在再来讲一下,什么是面向对象分析和设计。这两个概念相对来说要简单一些。面向对象分析与设计中的“分析”和“设计”这两个词,我们完全可以从字面上去理解,不需要过度解读,简单类比软件开发中的需求分析、系统设计即可。不过,你可能会说,那为啥前面还加了个修饰词“面向对象”呢?有什么特殊的意义吗?
之所以在前面加“面向对象”这几个字,是因为我们是围绕着对象或类来做需求分析和设计的。分析和设计两个阶段最终的产出是类的设计,包括程序被拆解为哪些类,每个类有哪些属性方法,类与类之间如何交互等等。它们比其他的分析和设计更加具体、更加落地、更加贴近编码,更能够顺利地过渡到面向对象编程环节。这也是面向对象分析和设计,与其他分析和设计最大的不同点。
看到这里,你可能会问,那面向对象分析、设计、编程到底都负责做哪些工作呢?简单点讲,面向对象分析就是要搞清楚做什么,面向对象设计就是要搞清楚怎么做,面向对象编程就是将分析和设计的的结果翻译成代码的过程。今天,我们只是简单介绍一下概念,不展开详细讲解。在后面的面向对象实战环节中,我会用两节课的时间,通过一个实际例子,详细讲解如何进行面向对象分析、设计和编程。
## 什么是UML我们是否需要UML
讲到面向对象分析、设计、编程我们就不得不提到另外一个概念那就是UMLUnified Model Language统一建模语言。很多讲解面向对象或设计模式的书籍常用它来画图表达面向对象或设计模式的设计思路。
实际上UML是一种非常复杂的东西。它不仅仅包含我们常提到类图还有用例图、顺序图、活动图、状态图、组件图等。在我看来即便仅仅使用类图学习成本也是很高的。就单说类之间的关系UML就定义了很多种比如泛化、实现、关联、聚合、组合、依赖等。
要想完全掌握并且熟练运用这些类之间的关系来画UML类图肯定要花很多的学习精力。而且UML作为一种沟通工具即便你能完全按照UML规范来画类图可对于不熟悉的人来说看懂的成本也还是很高的。
所以从我的开发经验来说UML在互联网公司的项目开发中用处可能并不大。为了文档化软件设计或者方便讨论软件设计大部分情况下我们随手画个不那么规范的草图能够达意方便沟通就够了而完全按照UML规范来将草图标准化所付出的代价是不值得的。
所以我这里特别说明一下专栏中的很多类图我并没有完全遵守UML的规范标准。为了兼顾图的表达能力和你的学习成本我对UML类图规范做了简化并配上了详细的文字解释力图让你一眼就能看懂而非适得其反让图加重你的学习成本。毕竟我们的专栏并不是一个讲方法论的教程专栏中的所有类图本质是让你更清晰地理解设计。
## 重点回顾
今天的内容讲完了,我们来一起总结回顾一下,你需要重点掌握的几个概念和知识点。
**1.什么是面向对象编程?**
面向对象编程是一种编程范式或编程风格。它以类或对象作为组织代码的基本单元,并将封装、抽象、继承、多态四个特性,作为代码设计和实现的基石 。
**2.什么是面向对象编程语言?**
面向对象编程语言是支持类或对象的语法机制,并有现成的语法机制,能方便地实现面向对象编程四大特性(封装、抽象、继承、多态)的编程语言。
**3.如何判定一个编程语言是否是面向对象编程语言?**
如果按照严格的的定义,需要有现成的语法支持类、对象、四大特性才能叫作面向对象编程语言。如果放宽要求的话,只要某种编程语言支持类、对象语法机制,那基本上就可以说这种编程语言是面向对象编程语言了,不一定非得要求具有所有的四大特性。
**4.面向对象编程和面向对象编程语言之间有何关系?**
面向对象编程一般使用面向对象编程语言来进行,但是,不用面向对象编程语言,我们照样可以进行面向对象编程。反过来讲,即便我们使用面向对象编程语言,写出来的代码也不一定是面向对象编程风格的,也有可能是面向过程编程风格的。
**5.什么是面向对象分析和面向对象设计?**
简单点讲,面向对象分析就是要搞清楚做什么,面向对象设计就是要搞清楚怎么做。两个阶段最终的产出是类的设计,包括程序被拆解为哪些类,每个类有哪些属性方法、类与类之间如何交互等等。
## 课堂讨论
今天我们要讨论的话题有两个:
1. 在文章中我讲到UML的学习成本很高沟通成本也不低不推荐在面向对象分析、设计的过程中使用对此你有何看法
1. 有关面向对象的概念和知识点,除了我们今天讲到的,你还能想到其他哪些吗?
欢迎在留言区发表你的观点,积极参与讨论。你也可以把这篇文章分享给你的朋友,邀请他一起学习。