1,软件编程技术的发展
软件编程技术与程序设计语言是分不开的。过去的几十年中,程序设计语言对抽象机制的支持程度不断提高:从机器语言到汇编语言,到高级语言,再到面向对象语言。每一种新的程序设计语言的出现都带来软件编程方法的飞跃。汇编语言出现后,开发人员避免了直接使用0-l编码,而是利用符号来表示机器指令,从而更方便地编写程序。当程序规模继续增大的时候,出现了以Fortran、C、Pascal等为代表的高级语言,这些高级语言使得编写复杂的程序变得容易,开发人员可以更好地应付日益复杂的代码,这一阶段的软件开发方法被称为“面向过程的”。但是,随着软件产业的迸一步发展,更大、更复杂的软件系统在需求中被提出,即使开发人员应用结构化程序设计的方法,仍然很难把握软件开发的整体局势。在这种情况下,作为降低开发复杂性的工具,诸如C++、Java等面向对象的语言产生了,面向对象程序设计也随之发展起来,软件编程方法学也由“面向过程”过渡到“面向对象(OOP)”时代。不难发现,编程技术与编程语言定义了人与机器之间的通信方式[1]。每一种新的技术都提供了一些新的方法来解决之前所未能很好解决的问题。例如,通过独立于机器的代码将晦涩难懂的0-1指令抽象出来:通过面向过程的编程语言使人们可以采用结构化的设计方式来构造较为复杂的系统;通过面向对象编程语言中的类来封装具体数据和方法的实现细节使人们将复杂的系统进行详细的划分等。每一种新的技术都提供了一种更为自然的方式来将系统需求映射为编程结构。编程技术的不断发展可以使人们创建复杂度更高的系统,反之亦然,人们允许复杂度越来越高的系统存在,因为新的技术可以用来处理这种复杂性。
2, OOP概念
OOP:Object-Orientedprogramming(面向对象程序设计)是一种程序设计范型,同时也是一种程序开发的技术。它将对象作为程序的基本单元,将程序和数据封装其中,以提高软件的重用性、灵活性和可扩展性。
OOP是一种运用对象,类,继承,聚合,消息传递,多态性来构造软件开发的方法,在系统构造中尽可能运用人类的自然思维方式。其主要的概念[2]如下:
(1) 对象(object):是系统中用来描述客观事物的一个实体,它是构成系统的一个基本单位,一个对象由一组属性和对这组属性进行操作的一组服务构成。
(2) 类(class):具有相同属性和服务的一组对象的集合,它为属于该类的全部对象提供了统一的抽象描述,其内部包括属性和服务两个部分。
(3) 封装(encapsulation):把对象的属性和服务结合成一个独立的系统单位,并尽可能隐蔽对象的内部细节。
(4) 继承(inheritance):特殊类的对象拥有其一般类的全部属性和服务,称作特殊类对一般类的继承。
(5) 多态(polymorphism):指一般类中定义的属性或服务被特殊类继承之后,可以具体不同的数据类型或表现出不同的行为。
OOP可以看作一种在程序中包含各种独立而又互相调用的对象的思想,这与传统的思想刚好相反:传统的程序设计主张将程序看作一系列函数的集合,或者直接就是一系列对电脑下达的指令。面向对象程序设计中的每一个对象都应该能够接受数据、处理数据并将数据传达给其它对象,因此它们都可以被看作一个小型的“机器”,即对象。
3,OOP的优点
OOP技术出现以前,结构化设计是程序设计的主流。结构化程序设计又称为面向过程的编程方式。在面向过程的编程方式中,需求被看作一系列需要完成的任务,函数用于完成这些任务,解决问题的焦点集中于函数。其中函数是面向过程的,即它关注如何根据规定的条件完成指定的任务。
在多函数程序中,许多重要的数据被放置在全局数据区,这样它们可以被所有的函数访问,同时每个函数都可以具有自己的局部数据。图1.1显示了面向过程编程中函数与数据之间的关系。
这种结构很容易造成全局数据无意中被其他函数改动,因此程序的正确性不易保证。面向对象编程的出发点之一就是弥补面向过程编程的这一缺点。在面向对象编程中,对象是程序的基本元素,它将数据和操作紧密地连结在一起,并保护数据不会被外界的函数意外地改变。图1.2显示了面向对象程序设计中对象、数据和方法之间的关系。
比较OOP和面向过程编程,还可以得到面向对象编程的其他优点[4]:
(1) 数据抽象的概念可以在保持外部接口不变的情况下改变内部实现,从而减少甚至避免对外界的干扰。
(2) 通过继承机制不仅可大幅减少冗余的代码,而且还可以方便地扩展现有代码,从而提高了编码效率,减少了编码出错概率,降低软件维护的难度。
(3) 结合面向对象的分析、设计,允许将问题域中的对象直接映射到程序中,减少软件开发过程中中间环节的转换过程。
(4) 通过对对象的辨别、划分,可以将软件系统分割为若干相对独立的部分,在一定程度上便于控制软件复杂度。
(5) 以对象为中心的设计可以帮助开发人员从静态属性和动态方法两个方面把握问题,从而更好地实现系统。
通过对象的聚合、联合,可以在保证封装与抽象的原则下实现对象内在结构和外在功能上的扩充,从而实现对象功能由低级到高级的转变。
4,OOP的缺点
面向对象的编程方法在软件开发领域引起了重大变革,极大地提高了软件开发的生产率,为解决软件危机带来了光明。但是,和其他编程方法一样,面向对象编程也并非完美无缺。例如,采用面向对象的编程方式能够很好地解决软件系统中角色划分的问题,将软件开发中的许多关注点都模块化,并能够把这些关注点的具体实现细节封装在类中。但是,在系统中还存在另一类关注点,它们并不是某一个模块或者类所特有的,它们可能横跨多个模块或类,例如日志功能就可以被系统中的许多模块引用。面向对象编程在处理此类关注点时所采用的办法就不够理想,从而造成了代码的混乱和分散[5~7]。可以通过一个简单的例子来说明采用向向对象编程实现横切关注点所带来的问题,这里给出一个封装了业务逻辑的类的实现框架:
public class BusinessClass extends BaseBusinessClass { //核心数据成员 //其他数据成员:日志流,保证数据完整性的标志位等 //重载基类的方法 public void performSomeOperation(OperationInformation info) { //安全性验证 <span style="white-space:pre"> </span>//检查传入数据是否满足协议 <span style="white-space:pre"> </span>//锁定对象以保证当其他线程访问时的数据完整性 <span style="white-space:pre"> </span>//检查缓存中是否为最新信息 <span style="white-space:pre"> </span>//记录操作开始执行时间 <span style="white-space:pre"> </span>//执行核心操作 <span style="white-space:pre"> </span>//己录操作完成时间 } // 一些类似操作 public void save(PersitanceStorage ps) {} }
在上面的代码中,存在两个问题:第一,其它数据成员不是这个类的核心关注点;第二,performSomeOperation()方法的实现做了许多核心操作之外的事,它要处理同志、验证、线程安全、协议验证和缓存管理等一些外围操作,而且这些外围操作同样也会应用于其他类。上述两个问题,归根到底是由于OOP未能将系统中被多个模块所共同享用的需求很好的模块化而引起的。为了解决横切关注点的模块化实现,一种新的编程技术—AOP面向方面编程(Aspect-OrientedProgramming)应运而生。