Code Bye

对面向对象和类的一些看法

 

做开发也有些年头了,想对面向对象和类谈一些自己的看法和见解。我做的基本都是企业级应用的开发,这里要说的侧重面向对象和类的设计在实际项目里的应用,而不是类本身相关的技术。

首先,根据我做过的项目来看,并没有什么项目是先设计类结构,再在那基础上进行开发的,基本上还是拿到需求和功能就开始开发了。我这里得声明下我们公司是比较大的,做的也都是大项目的,所以项目正规程度是没有什么问题的。在开发过程中,面向对象基本都是当成是一种技术在用,而不是一种设计思想。比如说拿到一个下订单的功能需求,就直接写个程序实现(这个程序是个类),而不是把这个下订单的方法写成“订单”这个类的一个方法。

关于这个问题,我也思索了很久,我认为当我们在打算开发一个系统的时候,首先一般都是关注这个系统需要实现哪些功能,如果系统比较大的话,会按照功能划分成几个模块,比如作一个进销存系统,会分成采购,销售,发货等模块,然后把采购相关的方法都写在采购这个模块下,而如果是按照类来设计的话,应该有一个货物类,它的方法是跨采购,销售等模块的,因为分类的角度不同,两种设计方法也不同。当然,你也可以把采购和销售当成是独立的子系统,下面分别都设计一个货物类,不过这样一来,重复的类会有很多,也没有必要。

然后,实际项目里的需求往往都是面向服务的,即用户下达一个指令或者点击一个按钮,系统完成一笔操作。在一个面向服务的方法或者程序里,会涉及到很多对象,这样的话如果按照事物分类去设计的话,这个方法可能同时牵涉到类A,类B和类C等,这样一来这个方法应该归于哪个类就不明确了,而且实际上如果只是为了调用方法的话,这个方法属于哪个类是并不重要的。当然你可能会说,方法会影响类的属性的值,这里就牵涉到另外一个问题,类的属性有点类似全局变量,当你用方法去改类的属性的值,之后再在某处使用这些值,这样的代码别人维护起来会很困难,因为别人不知道这些值是什么时候被改过的。我觉得更合理的做法是通过传参数来代替类的属性。

再说一个问题,我看过很多代码,我个人认为对类的理解是有问题的。比如说helloworld类,一个main,一个cout输出hello world,再比如说从数据库取数,有人会写一个get_data的类,我其实很想问,helloworld类,get_data类,究竟算是什么类,类都是具体事物的抽象,所以类应该都是名词,在helloworld这个例子里,应该是建立一个叫文本的类,里面一个方法输出helloworld;在get_data这个例子里,应该是建立一个data类,里面一个方法叫做get_data。大量的为了类而类,把动作行为也当成是类,这样跟面向过程的编程方法能有多大区别?

按照事物去分类是一件很麻烦的事情,在一个系统里可能会出现很多事物,并不是每种事物都需要设计成类,比如一个系统,有个叫做“业务员”的类,业务员有住址信息,地址既可以作为业务员的属性,也可以单独成为一个类,当然,什么东西应该被设计成类是有一定规律的,这里不作详细探讨,我只是觉得去思考哪些是类哪些不是类没有什么必要。而且即使你业务的类设计好了,还需要考虑技术层面的方法,比如数据格式转换的方法,设计一个代码扩展的方法,这些IT功能层面的方法就更加不容易归类了。

我认为在设计一个系统的时候,并不需要关注这个系统有些什么事物(类),而要关注这个系统能干些什么,用户在操作这个系统的时候,每一笔操作,都写成一个方法(当然这些方法肯定含有很多子方法),归于一个叫作“用户服务”的类。其实我的这种想法就是面向过程,只不过我把过程归类了一下。以上是一点我的经验,可能有些想法是有问题的,抱着讨论交流的目的发一帖,欢迎指教。

20分
我是来抢板凳的,
20分
楼主见解有理
20分
有些地方强调函数级编程,禁止类对像的成员变量,包括const的。。。。已到边缘。
引用 3 楼 greex 的回复:

有些地方强调函数级编程,禁止类对像的成员变量,包括const的。。。。已到边缘。

有的时候在远程调用一个方法的时候,为了数据不必在网络上传递多次,会把数据暂时存在远程类的成员变量里。
这种属于有利有弊吧,有利的地方在于提高了程序效率,不利的地方在于破坏了程序的结构。

20分
请牢记:源代码本身的书写是否结构化或面向对象或符合设计模式或敏捷…并不重要,重要的是你是否使用结构化或面向对象或符合设计模式或敏捷…的方法命名标识符、阅读、修改、检查、测试源代码。

意思是你程序结构看上去再合理,再简洁,也不一定比看上去一团乱麻的程序结构在运行或修改时更不易出错,更方便修改,出错了更容易找到哪里出错和具体出错的原因,更容易改正错误。

试对比
图书馆(对图书的分类够结构化了吧)

搜索引擎(可看作是扁平化任何结构数据,仅支持全文检索)
哪个处理信息更方便、更高效。

所以
与其费劲去重构代码让其看上去更简洁、更合理
不如费劲学习grep、sed、awk、……这类全文搜索和批处理编辑的工具。

结构越复杂,越难修改,越难除错。
有时(甚至大多数时候),看上去越合理、越简洁的代码,运行起来性能越差,出错时查找原因越难,找到出错原因后改正越费劲。

程序员要做的不是尽力避免错误,而是聚焦在快速发现并改正错误。真正以快速方式轻易解决错误,“快速的失败”远胜过“预防错误”。Fred George

面向对象只是一种编程思想。
再抽象的编程语言,最后不都变成汇编代码了吗?我们完全可以说汇编语言是面向对象、脚本化、动态化、泛函化、并行化、分布化的语言。

记不得哪位C++大牛在哪本学习C++的书的前言里面说过
“用C语言1000行源码能完成的工作千万不要用C++重写!”

做个可能不太恰当的比喻:
人想让狗帮忙逮只兔子,可是人说话狗听不懂,于是人发明了一种介乎人言和狗语之间的语言,即口令。
人想让电脑帮忙做计算,可是人话电脑听不懂,于是人发明了一种介乎人言和汇编机器码之间的语言,即C语言。
人对狗的口令得让人容易学、也得让狗容易懂。
C语言同样得让人容易学、也得让电脑容易懂。
相比之下C++、Java就是人学得费劲、电脑也经常闹不懂。

CodeBye 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明对面向对象和类的一些看法