OOP - 面向对象编程 - 学习/实践

1.应用场景

主要用于学习OOP的编程思想,以及如何正确地使用OOP进行项目开发。

2.学习/操作

查看源图像

1. 文档

14 | 实战二(下):如何利用面向对象设计和编程开发接口鉴权功能?-极客时间

04 | 编程语言的进化-极客时间

2. 整理输出

1. 如何进行面向对象设计?

面向对象分析[OOA]的产出是详细的需求描述。面向对象设计[OOD]的产出是类。//实际编码实现阶段则是面向对象编程[OOP]

在面向对象设计这一环节中,我们将需求描述转化为具体的类的设计。

这个环节的工作可以拆分为下面四个部分。

2. 划分职责进而识别出有哪些类

根据需求描述,我们把其中涉及的功能点,一个一个罗列出来,然后再去看哪些功能点职责相近,操作同样的属性,可否归为同一个类。

3. 定义类及其属性和方法

我们识别出需求描述中的动词,作为候选的方法,再进一步过滤筛选出真正的方法,把功能点中涉及的名词,作为候选属性,然后同样再进行过滤筛选。

4. 定义类与类之间的交互关系

UML 统一建模语言中定义了六种类之间的关系。它们分别是:泛化、实现、关联、聚合、组合、依赖。我们从更加贴近编程的角度,对类与类之间的关系做了调整,保留四个关系:泛化、实现、组合、依赖。

5. 将类组装起来并提供执行入口

我们要将所有的类组装在一起,提供一个执行入口。这个入口可能是一个 main() 函数,也可能是一组给外部用的 API 接口。通过这个入口,我们能触发整个代码跑起来。

后厨补充

...

3.问题/补充

1. 网友-有铭

04 | 编程语言的进化-极客时间

对象范式的原始概念其实根本不包括类和继承,只有:

1. 程序由对象组成

2. 对象之间互相发送消息,协作完成任务。

最初世界上第一个面向对象语言是 Simula-67,第二个面向对象语言是 Smalltalk-71。

Smalltalk 受到了 Simula-67 的启发,基本出发点相同, 但是最大的不同是Smalltalk是通过发消息来实现对象方法调用,而Simula是直接调用目标对象的方法。

Bjarne Stroustrup 在博士期间深入研究过 Simula,非常欣赏其思想,C++的面向对象思路直接受其影响,因为调用目标对象的方法来“传递消息”需要事先知道这个对象有哪些方法,因此,定义对象本身有哪些方法的“类”和“继承”的概念,一下超越了对象本身,而对象只不过是类这个模子里造出来的东西,反而不重要。

随着C++的大行其道,继承和封装变成了面向对象世界的核心概念,OOP 至此被扭曲为 COP ( Class Oriented Programming,面向类程序设计)。

但是COP这套概念本身是有缺陷的:每个程序员似乎都要先成为领域专家,然后成为领域分类学专家,然后构造一个完整的继承树,然后才能 new 出对象,让程序跑起来。

到了 1990 年代中期,问题已经十分明显。

UML 中有一个对象活动图,其描述的就是运行时对象之间相互传递消息的模型。

1994 年 Robert C. Martin 在《 Object-Oriented C++ Design Using Booch Method 》中,曾建议面向对象设计从对象活动图入手,而不是从类图入手。

而 1995 年出版的经典作品《 Design Patterns 》中,建议优先考虑组合而不是继承,这也是尽人皆知的事情。

这些迹象表明,在那个时候,面向对象社区里的思想领袖们,已经意识到“面向类的设计”并不好用。只可惜他们的革命精神还不够,delphi 之父在创建.Net Framework 的时候,曾经不想要继承,在微软内部引起了很大的争议,最后是向市场低头,加上了继承。

2000 年后,工程界明确的提出:“组合比继承重要,而且更灵活”,Go和Rust也许是第一批明确的对这种思路进行回应的语言,他们的对象根本不需要类本身来参与,也能完成对象范式的多态组合。

历史让 C++走上了舞台,历史也终将让 COP 重新回到 OOP 的本来面目

作者回复: 赞。很好的学习材料。

2. Junho

04 | 编程语言的进化-极客时间

关于许老师说关于继承的看法,我拜读后深有同感。

尤其多层的继承,理解成本多项式上升。有点像,你想了解清楚眼前的这位妹子,不但要知道她已有的一切(所有逻辑成员),还要知道她所有祖上(继承链)的一切(包括private),更要知道这位女孩做了什么叛逆行为(override),还不得不知道,这些叛逆行为,会对祖传的既有秘方产生怎样的影响(调用override函数的函数)… 回顾一下最近自己工作的代码,的确不少的设计,最后会倾向于组合的方式。原本的想法主要是感觉,用继承的话,更像是可以去为了聊天而去相亲…不好意思说错了,是为了面向对象而去面向对象,一个月后,自己理解这部分设计也有不小的成本。读了许老师的课,才从更深层次的意识到这个特性的确有它天生的缺陷。

作者回复: 挺形象的比喻

3. 东次哒呲

使用java四年了,看到封装,继承,多态的描述,特别精准,又有了更深刻的理解。

不了解go语言,比如有一个表单的基类,里面有基本的处理,子类继承这个基类,有自己特殊的实现。

这种情况,如何用组合实现呢?

作者回复:

这是受继承思维的影响了。

其实继承实现了代码复用和多态两个东西,揉在一起。

在go里面,组合实现代码复用,接口实现多态,彼此完全独立,非常清晰。、

4. 觉

感恩大佬分享 随喜大佬 学生是java使用者 个人认为类之间具备‘is-a’的关系这种情况时 还是很有必要的;继承使所有子类公共的部分都放在了父类,使得代码得到共享,避免重复。 这是学生一点自己的理解 望老师批评指正,再次感恩老师分享这么好的课程 我当奉持 如法修行

作者回复: 逻辑上如此,这也是继承被发明的原因。但是软件工程的实践表明,继承带来了收益🈶️,但它带来的伤害更大。

5. 网友-青山

老师您好,我有一个不太理解的地方,是我不太理解您说的继承是个过度设计的原因,我目前在架构过程中大量的使用了继承,而且我也觉得继承功能将我的代码功能高度抽象化,给我带来了很大的方便。我想咨询下您如果不是用继承的话,用什么方法替代继承的功能呢?

作者回复: 建议继承只使用接口继承;正常情况下,优先用组合;当然因为大部分语言的组合功能不够强大,有时候从便捷性的角度继承可以适度使用,但是应当意识到如果过度使用继承对工程来说是有害的

4.参考

14 | 实战二(下):如何利用面向对象设计和编程开发接口鉴权功能?-极客时间

04 | 编程语言的进化-极客时间

后续补充

...

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值