( 1 )、从编码习惯思考面向对象
示例: public boolean insertCorporation(Corporation corporation);
这是一个接口 CorporationService 里的方法,此接口主要用于管理系统里相关的公司资料,包括新增、编辑公司信息等。方法 insertCorporation 用于新增公司资料,乍一看此方法型别符合逻辑,没有什么问题。但是,当我们仔细思考, insert 这个操作语义是我们通常在业务上所说的“新增”么?笔者觉的有待商酌。 insert 在软件开发领域里,更多地是表示数据的插入操作,一般指 DAO 模式里的数据插入方法。
谈到这里,读者可能要问?笔者不是说“面向对象”么,怎么谈什么语义!但是,笔者想强调的是,这里的问题看似很简单,其实是关系到对“面向对象”的深知熟解。笔者认为:此处采用“ insert ”签名方法,实际是传统的面向过程或者说面向数据的思维习惯,“面向对象”思维是对真实世界在软件世界的映射和虚拟,它提倡软件类名、数据对象名、操作名源于真实世界,当然也加工生产虚拟的对象和操作。
也许有人认为笔者小题大做了,也许举例不太清晰,但常言说得好:“一叶知秋”,这些的小瑕疵里透露出的是编程思维习惯:面向对象必须从细节做起,从思维和行为做起 。
( 2 )、从类的职责上思考面向对象
参与过多个项目的开发,最多发现的一个典型模式是:数据对象,一种仅含有数据属性及其 get/set 方法的类。很多次,笔者也默认了这个做法。但是在一次项目重构中,作者给一数据类稍微增加一些要操作类属性的方法提供给别的类使用,结果听到了反对声音。
这样做真的不妥么?相反,笔者认为应该很少存在纯粹的数据类,“面向对象”划分类的最基本原则就是基于职责,一个类因职责而生,而且可能因为一些职责而设计出一些类来 。笔者认为,跟某数据类属性极其相关的职责、或者针对其数据简单的基本的操作就应该是数据类的。
这里也许就是一直在争论的“失血模型”、“有血模型”等的问题,没有定论。但是,笔者认为:职责是面向对象的根本要素,每个类都应该有简单、明确、单一的职责,这样才能开发出结构合理、易理解和维护的系统 。
( 3 )、“面向对象”是万金油么?
不是,面向对象开发技术带来很多好处,比如系统可理解性好、可维护性高、可重用性和可扩展性高等。但是纯粹的面向对象,前期开发成本是很高的,有更高的设计要求,需要更好地进行面向对象思考和分析;同时,按照目前的开发技术来看,有时候不能完全解决系统的性能“瓶颈” 。
a 、 对于许多高性能、大规模并发、分布式计算的应用,更加强调面向过程 \ 线程的思维 ,这时候虽然采用了对象编码来实现应用,但是思维的关注点已经不是对象,分析和设计的中心是计算的过程。常见的使用场景有:利用存储过程执行业务逻辑(笔者曾参与个项目,有时候业务逻辑的操作大部分在存储过程里执行)、直接针对数据库计算;高并发系统多线程编程时,在设计上也更关注线程及其交互。
b 、在开发成本方面,首先目前的面向对象数据库还不成熟 ,利用一些新的面向对象数据库技术,势必提高开发难度。其次, 纯粹的面向对象,也需要良好的架构和设计,更好地理解业务 ,对设计开发人员的要求更高;而且“好的代码是重构出来的” 。
c 、在适用场景上,目前面向对象编程语言在嵌入式应用中还不太适应 。传统的直接基于硬件编码的应用大都还是采用面向过程 \ 结构编程语言,特别是单片机、数控应用等。笔者认为主要原因是:面向对象语言的性能问题,采用对象语言编码的程序,文件较大,运行时空间暂用多,速度较慢。、
谈论的不多,笔者在这里采用从行动到思维,再过渡到原因的方式关注了一次面向对象。正所谓:知行合一,笔者认为,对待面向对象 ,我们也应象处理生活中的重要事情一样,要在如何做、怎么想、为什么上多下些功夫 。而且也只有在不断的思考和总结之后,我们才能有更多发现和收获,才能提高,才能将面向对象技术有的放矢、更加合理地应用在生产中。寥寥数字,言简意切,希能与读者共勉。