很多书上会写着,对象是具有数据以及对这些数据提供的操作的集合。这是一个极其错误的认识。这里的对象可以简单理解为类似于现实生活中的对象,生活中是以对象为个体,并且不同对象间通过发送消息作为交流沟通方式。例如,社会的交换活动,任何人都是通过发送消息到另一个对象去请求其所提供的某种服务。整个面向对象系统就是以对象间的互相交互,协作形成的一个运行系统。 至于类,只是 同种性质的对象的抽象体,是一个抽象概念,它只是用来让编译器认识的。
每一个对象都提供某些服务,当然都是以方法的形式存在。而且,这些服务可能同时需要一些数据信息,这两种即构成了对象对外提供服务的基础。也是最常见的。那种理解为先有数据信息,再由服务是不对的,否则,将难于进行对象抽象以及设计。而且,这些方法不是专为数据服务或者说外界并不是为了访问数据,而时这些数据根据服务的需要决定需要什么数据信息以及如何暴露数据信息。与此相反的访问方式,抽象数据结构是个典型,这种方式以数据位中心,并不是面向对象的核心所在。 面向对象的核心是整个世界的写作过程,是以服务为基石,它并不是以数据位中心,而是以服务为中心,各对象通过接口暴露自己的服务,为外界提供服务。这也是面向接口编程的主旨。所以面向对象应该是先有对象行为,而这些数据时反过来为这些行为提供数据基础信息,为之提供数据服务的。这与传统的ADT,数据+对数据的操作方法时截然不同的,尽管其结构及其相似,它是方法依赖于数据。
基于这些原因,一个无数据的对象出现时很正常的,而且是占据很大部分。这些对象称之为无状态对象。即两个同类对象,其行为时完全一样的,因为已经少了特定数据信息的依赖关系。现实生活中也确实存在这类只提供服务的对象,该对象提供的服务本身互相依赖,或同类,或是以某种一致的方式向外提供服务。而在面向对象的系统中,这种无状态服务对象是基于业务需求而定的。同样的对象,在一种业务系统中,它是有状态对象,需要某些依赖信息,而在另一个系统中,可能就以无状态对象出现,外界并不关注其数据,而只是想获取其服务,这时这些数据信息并不存在意义,尽管它可以被保留住,对象里的服务于数据,存在服务依赖于数据,以及不依赖2种关系。然后,大部分是有依赖关系的,对于无状态对象,有2种处理方式,其一,既然无状态,则可分布至各自不同的Util类中,如
class A {
sourt(..);
run(..);
study(..);
}
这里A的任何对象都是无状态的对象,则应放入不同Util类中并以static修饰它。这种无状态类是不应该被设计的,因为他充满了大杂烩的坏味道。职责不明确,更不用提SRP了。并且给这种类取名也是一个大问题。再看,
class OrderService {
add(...);
remove(...);
update(...);
}
这个OrderService的一个实例,同样时无状态对象,然而这是一个合理的设计。因为其很好的吻合了对象的语义所在。提供了一组一致,互相合作,同类服务的服务方式。
有时会有很多对象,其提供服务时相同的,但是其具体实现的内部细节不同,如:
基于class RemoteOrderService, class LocalOrderService所生成的对象,而且是很常见的,且其依赖的数据信息时不同的,这在生活中很存在的合理性。如
RunnerA {
run(...){
使用拖鞋跑
}
}
RunnerB {
run(...){
使用自行车跑
}
}
然而,我们无论创建RunnerA还是RunnerB的对象,我们都不关心其实现细节,也就是我们根本不关心内部数据的依赖细节,我们只关心其为我们提供的服务,它能使我从一个地方到达另一个地方。因而,其数据对我们而言是透明的。我根本不想知道,你是使用什么数据,怎么run的。因而这种基于服务提供的方式,使得我们使用了一个只包含所提供服务的类型Runner。并且在我们看来,它隐藏了提供的服务的实现细节,这就是接口。
interface Runner{
run(..);
}
而多态的性质,这时发挥了很好的作用。形成了一个种特殊的依赖关系,此时,client与Runner的依赖关系远远强于Runner与其实现类的依赖关系。这也就是面向对象几大原则之一的DIP了。
因此,面向对象系统本质是以接口为核心的系统,每个接口就代替一个ServiceProvider, 然后,发送消息请求构成了一个协作系统网。
而另一种极端,就是对象无行为。当然,其是有状态对象。这些对象都是不同的,尽管他们同属一类。这种对象的出现,使得面向对象的语义受到了很大的冲击。因为这种脱离了对象是以服务为核心的语义。一个对象没了方法,那还谈什么服务。然后,现实生活中的确是有些东西是无服务的,例如book, 而这种被称为实体对象。这里并不是说该实体真的无服务,而是其所提供的服务其实是无用的,或无意义的。因此,宁愿将其行为全部去除以保持其整洁,又不至于冗余。因为这同样取决于业务系统的需求。这一种情形被称为贫血模型,即不具行为之对象。不管贫血与否,其设计起源于业务系统的需求。设计是多种多样的的,面向对象本身要求从问题领域中提取对象是件难事,同时对象的职责分配更是一件难事。所以,出现了许多关于这方面的方法论,如CRC, 信息专家等职责分配方法以及大量面向对象设计原则,设计模式等等。因而,面向对象设计本身是一门高深的学问。并且取决于个人的经验以及知识面,处理业务,分析,解决各种问题的思想,特别是基于某特定领域的业务经验。
我们发现了再生活中的不基于服务的,不基于消息发送请求服务的对象,我们仅仅能说这些对象不直接参与对象协作网。因为没人能透过该网享受或请求到某种服务。但是,它是作为一种间接写作者出现,它作为其他对象间的请求服务的一种辅助,就好比交换系统中的物品,它是在服务对象间的请求链中流通,而流通过程中,没有一个人会把请求发向该物品,他们可以持有它或流通它。当然,有可能在流通中,稍微检查物品是否合法等。而这时该物品也仅仅提供了合法检查服务而已。跟基于对象服务的协作网是大小巫了。呵呵。
根据面向对象设计原则以及经验的权衡作出合理的设计时必需的。在这些不同的对象类型中,最容易被发现并提取的就是,贫血模型的对象。因为他直接反应世界,不是只有程序员能想到,而是生活中的所有人都懂。这就是面向对象的好处。在业务领域中,业务专家起到了相当重要的作用。这就是面向对象的好处。在业务领域中,业务专家起到了相当重要的作用。如,图书管理系统,大家都会想到实体类,如book, student, library等等。这些就是不提供服务的对象。而且这些信息基本都会被持久化进DB或其他地方,散发着某些DB的味道,因而这些对象一旦被冠以DB味道后,大多数人的初衷发生了微妙的变化,他们把设计的焦点转向了DB,而远远脱离了他原本想做的基于面向对象的设计,久而久之,很多人习惯了基于DB的设计,一个系统一上来就开始建立表。把所以业务逻辑寄托在DB身上。所以,DB责任之大可想而知。因为面向对象设计与之相比是何等之难。这时候,所有的业务逻辑都依赖于DB,整个业务系统设计严重侧向DB,一些以表为核心。从一个表能看出所有业务,因为人们太习惯于关注信息了,而且DB是基于二维表的,从小学就学过,极其容易,管理层的家伙们很容易明白,这时管理层也参与了项目讨论,很好。对着那些表,指着点着。这就是技术。
posted on 2009-10-29 08:49
zhqh 阅读(365)
评论(1) 编辑 收藏 所属分类:
面向对象