计算机系统应用教程网站

网站首页 > 技术文章 正文

关于面向对象编程思想的一些思考 面向对象编程思想的主要特征都有哪些

btikc 2024-10-24 09:19:50 技术文章 7 ℃ 0 评论

最近在评审团队的代码,发现还存在一些问题,比较重要的问题是面向数据库编程和用面向对象的语言写着面向过程的代码。为此对面向对象编程思想进行了一个总结,以便尽快建立面向对象编程思想。

在此形成文字稿,分享出来大家一起探讨。

言归正传。

整个编程语言主要经历了从面向过程的语言到面向对象编程语言的过程(其他编程思想不在本文讨论范围之内,如:面向函数编程)。

图:编程语言的发展分析

面向过程编程语言主要代表是汇编、C语言等。

汇编语言对开发者要求高,开发效率低,除非某些必要场景,如:BIOS,现在很少有人用其开发。为提高开发效率,1972年,美国贝尔实验室的丹尼斯·里奇发明了C语言,C语言的开发效率大幅提高,随着面向过程编程的指导思想——“数据结构+算法=程序”深入人心,很多程序员在尼古拉斯·沃斯画的圈圈里打转,不能自拔。本人认为面向过程编程思想是账本思维,引导人重点关注这本账,即数据结构,其他的操作,即算法,都是去修改操作这本账,账本和账本操作的方法两者的关系在人看来割裂,关系弱,当后期需求变更时,不容易掌握,控制不好需求的改动范围,传染不好控制,导致后期演进维护成本高。

面向对象编程语言主要代表是C++、Java、Go等。

C++语言是集大成者,语法特性丰富,开发效率高,但由于语法特性过于丰富和灵活,导致难掌握,团队协作时,容易出问题,如,多继承会是子类有多个父类,经过多重继承,子类的父类有相同方法等,后期维护会找不到北,还有容易出指针,为此,如果选择用C++开发,则会限制语法范围,在团队限定的语法规范内研发,总体来说,对底层性能要求高的。

为解决C++的这种弊端,适时地推出了Java语言,Java语言拥有很多特性,如:跨平台、单继承、反射、抛弃指针、GC等。

1、跨平台解决一次编译多处使用,提高程序的可维护性。

2、单继承解决纵向依赖混乱问题。

3、反射本人认为是Java最大的特性,反射的根源在于Java相较于C、C++保留了Metadata信息,因此,Java可以根据对象的字节码动态构造对象,而C、C++在编译时未保留这些信息,因此,无法从二进制中动态生成对象,这也是Strus、Spring、Hibernate等系列组件存在的基础,正是由于有了这些丰富的Java中间件,促进了Java生态的发展,在web应用开发领域一枝独秀。

4、GC则把程序员从繁杂的内存申请与释放的管理中解放出来,同时GC使得内存的利用率更高,降低出现内存碎片化的概率,但GC管理内存时会带来性能损失,具体可以参考GC的相关机制材料,本文不做深入探讨。

Java语言由于支持跨平台的特性,在实现上需要先编译成字节码,在执行时再由Java虚拟机解释执行,虽然Java虚拟机采用各种机制进行优化,效果也较明显,但与C/C++从语言效能相比,性能总体还是存在一些差距。

Go语言应运而生,Go的目标是21世纪的C语言,Go是面向对象的语言,语法接近C语言,但对于变量的声明有所不同。Go支持垃圾回收功能,取消了继承,使得对象的纵向关系弱化,只能使用对象的横向聚合与组合关系,从语法机制上降低乱用的概率。

从编程语言的发展趋势来看,编程语言对开发者的要求越来越低,语言的开发效率越来越高,但对开发者的设计能力却要求越来越高。

实际上,大部分人都是用着面向对象的语言写着面向过程的代码,导致开发效率低、产品维护和演进困难。造成这些问题的根源在于对面向对象精髓的理解有所欠缺,本人认为主要体现在两个方面:

1、思维定式问题:还是以记账的方式在思考问题,设计时首先考虑数据库怎么设计,数据要怎么存,有了这个账本后,再在账上进行增删查改,而不是采用先物化成对象,再抽象成类,然后通过聚合和组合进行对象组装,编程思想的认识还是停留在面向过程的编程思维中。

2、思维误区问题:在语法学习时,好像都懂,但一旦与具体业务结合时,没有有效的分析手段——如何物化抽取对象,对象的功能划分、对象间该如何组合和组装等等一系列问题。最终的表现还是用面向对象语言写着面向过程代码。

即,还是“数据结构+算法=程序”的思维方式,基于我的理解,我尝试着对面向对象编程给出我的理解“对象+组合/聚合=程序”,供大家参考。

本人认为,当前面向对象编程模型的最佳实践方法是领域驱动开发,领域建模的核心原则是“聚合根+充血模型”,通过领域建模,物化抽取对象,按充血模型原则把相关的功能划分到正确对象中,然后根据场景关系组合/聚合对象间的关系,形成聚合根。

以一个简单报账场景为例,简要说明领域驱动开发的领域建模的过程:

1、第一步:抽取报账人、报账单、差旅票、住宿票证等为一个个对象,即物化过程,随之把总金额计算、行程金额计算、酒店金额计算等相关的功能按充血模型的原则放到合适的对象中,让各对象各司其职,类似于汽车工业的各种零件加工。

2、第二步:建立对象间的聚合/组合关系,如:报账人组合/聚合关联报账单,报账单组合/聚合挂链住宿票证和差旅票证等,形成聚合根的方式,即对象组合/聚合形成聚合根的过程,同时把对象间关联的相关功能,按充血模型原则放到合适的对象中。借助面向对象的语言组合/聚合的特性进行关联关系的组织,类似于汽车工业的汽车组装过程。

在组合/聚合过程中,有两个需要特别注意。第一,对象间尽量不要形成回环。第二,对象的访问,需遵循只能从聚合根进行访问,即,形成单向的聚合和访问关系的秩序,使得对象间关联关系和访问原则简单,便于分工协同、对象组装以及产品的的维护和演进,提高生产效率和降低维护演进成本,类似于工业大生产中的标准化分工、工序化协作以及产品售后的维护和产品的演进等。

掌握了面向对象编程思想的精髓,用面向过程的语言同样可写出面向对象的代码,达到“无招胜有招”和“手中无剑,心中有剑”的境界。如:用C语言编写的Linux、PostgreSQL处处体现着面向对象思想,本人也曾用PL/SQL编写过面向对象的代码,无非这部分代码是编译器干,还是开发者自己干。

领域驱动开发是本人认为当前阶段较好的一种面向对象编程思维训练的方法,推荐大家可以深入学习,后续本人将会对领域驱动开发的进行专题讲解。

面向对象编程思想是一种很好的思考问题的方法,类似于工业化分工协作的大生产的方法。如果理解深刻,我们也可以像工业化大生产一样生产软件。

共勉。

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表