谈谈我对面向对象编程的经验看法

前端时间,我看到了网上的一些人对于面向对象的弊端的讨论,里面对于面向对象的各种争论一场火热,这引起了我的深思。毕竟我也有多年的编程经验,在编程的过程中面向过程和面向对象这两个编程范式也是经常的使用,也算是有了一点心得。附上原讨论入口讨论帖。我在这里并不像抨击任何人的意见,只是阐述我的一种看法。

在编程中,我是非常推崇面向对象的编程思想的。在我看来,面向对象可以很轻松的分割问题域,通过面向对象的封装,多态和继承,可以很轻松的开发庞大复杂的程序。

一个人的思维逻辑能力是有限的,他不可能面面俱到的处理到上到用户交互界面,下到磁盘存储形式的所有技术细节,这样在开发中就需要利用到封装的思想,封装的思想让程序员更加关注逻辑调用而忽略底层实现,这样开发起来更加顺畅。思维上顺畅,可维护性也大大提高。因为一个数万行程序的开发工作不是一个人能够完成的工作量,这样巨大的工作量之后更需要有人进行维护,面向过程的编程方式会在代码上暴露更多的技术细节,这对于理解整个系统的架构思路非常不利。因为看不懂,所以代码维护起来很难,很容易出现问题。面向过程虽然也能够封装,但是这种封装是人为添加到逻辑层面的,对于特化的编程还凑合,但是面对普式的编程比较低效了,面向对象天生鼓励人们对于任务进行分割和封装,因此更加适合大型项目的开发和维护。

面向对象拥有一个非常大的有点,就是多态,多态的实现可以在程序运行的时候动态的调用对象的方法,实现一个函数调用不同对象,产生不同行为的神奇效果。这对于问题抽象非常有益,比如利用面向对象的思想,将鸡和鸭抽象化,他们都有吃食,喝水,奔跑的行为,都属于禽类。这是他们的特点,那么我编写一个针对禽类操作的方法,就可以把他们传进去,这样就可以在传鸡的时候,吃食的方法表现出”啄“,传鸭的时候,吃食的行为表现出”铲“。因为不同的程序模块在面对同一个输入的时候可以产生不同的输出,可以在运行时刻通过传入的不同模块组件,动态的构建系统,这在模块化和组件化的系统中非常有用。可以说,多态是人们远离利用面向对象编程的重要理由。

面向对象的另一个重要特点就是继承,继承使得人们能够站在巨人的肩膀上征战世界,利用一个已经封装好的类,能够快速的编写新代码,利用现有类提供的接口不仅仅是减少代码量的问题还有系统适配的问题。通过继承的方式对组件功能进行拓展,配合着多态的使用,简直是系统化的编程的一种大杀器。无论继承设计的目的是什么,在我看来它确实是一种威力巨大的武器。用来拓展系统的功能实在是太适合不过了。

然而为什么有些人对于面向对象的编程方式如此诟病呢?

我认为是绝大多数人对于面向对象编程的误解在成了面向对象编程的错误使用而带来的一些问题,对这些人造成了困扰。


封装的经验:

首先来说,封装是一个非常好的问题解决思路,是构建大型程序的好手段。封装这个工具的出现时为了封装底层细节,使得程序员能够更加关注顶层逻辑实现的。也就是说,我们需要通过封装来达到降低程序员逻辑负担的目的,例如一个模块的初始化过程,我们不能将所有的技术细节暴漏给上层程序员,那么与未封装相比还有那些优势呢?我们可以很简单的告诉上层程序员,调用这个函数,所有的变量属性环境都初始化好了。构造函数可以做这些事情,但是并不推荐,应该单独设立一个init函数,这样不仅不降低抽象能力,同时还保存着简单的性质,能够通过返回码等方式报告初始化过程中出现的意外情况。使得上层调用方能够返回信息处理各种意外。另外这里提到了初始化不得不提一下,强烈推荐一个类只有一个初始化函数,一个默认构造函数,这样编程的附带比较小。即使面对必须多个构造函数并存的情况,那么一定要保证通过这几个用于初始化的函数,初始化出来的数据结构是一直的,达到统一化的目的,不让通过不同的构造函数初始化出来的变量具有不同的性质,这就可能造成你的程序陷入bug无限,完全不可维护的境地。

类对象中只暴露出方法,屏蔽属性和字段,这样的优势很明显。除非组件极其简单,否则,每个类都可能在后期维护的时候,进行修改,程序架构之初如果没有预料到这种情形,简单粗暴的暴漏出字段和属性,在后期维护的时候将会毁灭你的程序。

在对象方法设计之初的时候尽量将方法与类本身解耦,也就是,最好在设计之初的时候,就尽量减少直接调用类的属性,而是通过函数的方法参数将类属性传进去。我们在编程的时候,需要的是封装,但是封装同样存在一些问题,那就是,界限不好确定的问题,当代码一多,程序就开始晦涩难懂,即使不断的重构,还是收效甚微。这对于排故来说有些困难。对于这种问题,我也没有非常好的办法。现在我基本采用的封装是对外部封装细节,不需要对外面暴漏的细节全部封装起来,也就是public方法对外封装一切,而private方法则暴漏一切,所有的方法,能够使用局部变量的绝不使用全局变量,能够使用成员的绝不使用静态变量,能够从接口传进来的绝不使用内部隐式调用。从类的结构上来看,类是一个多入口的小程序,每个类的public方法都是一个入口点,设计程序的时候一般情况下,将所有的保存状态的变量交给入口程序掌管,接收调用的函数和方法,只使用临时变量。这样逻辑更加清晰,调试起来更加容易。


多态的使用:

有些人认为多态是一个解决不断变化的需求的神兵利器,认为通过相同的调用方式产生不同的输出结果,这样就能应付所有的产品需求了,然而大多数这样认为的人都折戟沉沙了。为什么呢?根据我多年的编程经验来看,我认为这是两种不同思路强行捏合在一起造成的恶果。是这些人错误的使用了多态的结果。没有任何框架能够适合一切情况的,产品经理提出来的功能能够被完全归类为同一类操作么?既然不能用同一种思路来操作,那么使用多态还有什么意义呢?

从软件运行的步骤上来看。多态的使用是为了利用同一种方式统一的调用同一类组件达成不同目的,它成立的前提在于你必须预料到所有可能的情况,构建出一个完整的最小系统接口,新的系统组件通过这个实现这个系统接口,能够达到既扩充了系统的既有功能又实现了对既有系统零更改的目的。这种情况非常适合插件化开发,而且是在已经定型的系统上进行插件开发,当然前提是你为了这种插件机制提供了内部的兼容机制。如果原来的系统架构设计垃圾,这种方式是无法完善整个系统的设计的,不能因为今天觉得以前的设计应该增加一个接口,就增加一个接口,却又不想改老程序,这样谁来调用你呢?有一些变态的架构师为了实现这个目的竟然连Java的反射都用上了。利用反射运行时关联等手段,成功的达成了这一个丑陋的目的之后,程序的逻辑代码就成功的从程序下放到了配置文件和数据库之中,管理困难,运行缓慢,bug奇多。备受其害。


继承的使用经验:

我认为继承是一个好东西,然而无论继承多么好都不应该滥用。拥有继承和多态相配合,程序很容易出彩。

继承不能滥用就表现在,继承应该有个原则,如果不是需要用到超类的所有功能就不要继承超类,因为这会带入乱七八糟的功能,给编程造成负担,引入bug。

继承可以将同一种操作提取出来,这样就可以少编写一些代码,这不仅仅省了一些力气,同样能够提高系统的可靠性,免得在基础功能上引入新bug。

继承最适合实现一些基础的操作,比如在窗口程序的开发中利用基类实现消息循环,空间之间的关联等操作,强烈反对胡乱继承,引入一堆不需要的方法和接口,最恶心的就是Java的swing类库,这个实现的确实挺经典的。但也是挺肮脏的,其中包含了巨量的无用接口,这些从根对象层层继承下来的用不到的接口乱七八糟的放在一起,糟糕透了。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值