1、抽象现实问题的方法不容易被开发者真正掌握。分解问题域中对象一般的思考方式有以下两种,一种是抽象对象的性质,这种方法实际上就是对象继承,第二种就是对象组合的方法。在经典的理论中认为对象的继承是面对对象方法的实质,但是不符合大多数人的思维习惯。对于一个轮胎而言,人们更愿把它看成轮箍、外胎、内胎等等结构的组合体,而不是抽象成这样的层次关系,橡胶-〉含有金属的橡胶-含有金属的圆形橡胶-〉轮胎。
2、分析到设计仍然不能平滑的过渡,在分析阶段产生对象,往往有很多现实的名词,这影响了设计者的思考,使他们不能关注对象在问题域中的关系,往往受到这些名词其他含义影响。假定普通的企业管理系统中,分析作了人-〉公司职员-〉高级职员-〉经理的抽象,设计人员往往会被人、经理、高级职员这些名词的影响,不能把这样的现实对象很好的映射到程序结构中去,甚至会去定义人的姓名、年龄这些属性,然而这些属性在问题域中是不关心的,实际上在程序结构中人这个对象会和真正的人概念完全不一样,之所以抽象这些对象实际上为了提取问题域中的静态关系和动态关系,现实的名词干扰了设计者。
3、面对对象方法产生的软件没有完全实现宣称的软件复用和简化维护的目标。在没有完全采用抽象对象性质的方法的时候,实际上完全采用也是很困难的,大多数人习惯于把复杂的事物分解成一组组合的对象,把简单的事物进行抽象,在这种情况下产生的软件结构是复杂的,对象组合之间必然充满了复杂的消息,要进行重复使用和维护当然是不容易的。
4、缺乏评价一个面对对象设计的标准,一个设计,或者说怎样做出一个能够实现软件复用、降低软件复杂性的设计,没有很好的理论支持。这本身就是由于对象抽象的灵活性造成的,不同的人对同样的问题完全会有不同的抽象方法,面对对象的方法不限制人们抽象的方法,或者说根本没有一套抽象的方法。我说的是抽象,和对象组合对应。缺乏标准,也必然造成软件复用困难。
为了解决这些问题,很多人进行了回归,我要说一些大逆不道的话了。第一个概念把继承分解为接口继承和实现继承,认为对象实际上是实现和宣称的方法集组成的,在现实的设计活动中,他们找到了复用的好办法,因为他们把接口和实现分离,这样在通过同样的接口就可以操纵不同的对象,而不用关心背后对象的细节,这样降低了对象之间的关联程度。第二个概念,尽量使用对象组合而不是继承,在把继承分解以后,就会很自然的发现,纯虚的基类实际上成为了对象的接口,而且为了复用的方便,几乎完全不要实现继承,因为复用是对象本身,而不是用它的基类,所以定义一个良好的组合成为了关键,而且继承也会为这种复用带来麻烦。我把这种解决方法称为回归,这是面对对象向结构化的回归,或者说结构化方法的延伸。在对象进行复用的时候,一般不使用已经成型的对象,而是使用基类,复用的是基类已经实现的方法,当然这样做,需要深刻理解原作者的意图。一个只有一个纯虚基类的对象和一个模块有什么差别呢?这是模块的复用。复用的只是接口,也就是一组定义,要实现支持同样接口的不同对象,需要完全重新设计,实际上并没有代码复用。他把实现的复杂性推给了后面的设计者。如果仅仅把接口复用当成分析,在实现这个借口对象的时候仍然坚持实现继承,也就是实现的时候仍然分层,那么这当然是可取的,但是我看不出需要接口继承的意义。在这种方法下,设计者更倾向于进行问题的功能分解,举个例子,设计企业的管理系统,设计者很可能在这种思考方式的主导下,划分成财务部,人事部,业务部。这完全背离了面对对象方法的初衷。
大多数问题是复杂的,习惯总是明智的,把一个大的问题分解成小问题,在解决小问题的时候使用抽象的方法,可以说是一个很好的折衷,也是很有效率的。但是不能把整个问题都细化,或者说完全取消实现继承,如果那样我看不出这还是面对对象。我更愿意看到结构化方法和面对对象方法的融合,而不是盗用了面对对象的概念行结构化的做法。在对于评价分层抽象,或者说分层抽象指导原则、模式,几乎没有,这不能说是完整的。就像气宗和剑宗构成了华山派一样,独孤九剑好像是绝种的剑宗武功,虽然难炼,但是杀了岳不群。
延伸阅读
文章来源于领测软件测试网 https://www.ltesting.net/