浏览 2334 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2007-10-05
1. 再次小结领域模型的种种观点: http://www.iteye.com/topic/17579 2. 总结一下最近关于domain object以及相关的讨论 http://www.iteye.com/topic/11712 另外,robbin还在下面的帖子中提出 [Hibernate实体类 != 领域模型] http://www.iteye.com/topic/11608 其实Domain Object不是一个语言层面的概念,因而如果拿它来对应于实现层面的某一个类,那么很多时候你是无法对应上去的。也就是说,在实现的层面,有的时候你需要多个类或者一个包来实现所谓的Domain Object。如果从这个思路来看,关于Domain Object的实现是应该是贫血模型、失血模型还是充血模型之间的区别也就并不是那么大了,其实本质是你用一个类还是多个类去实现Domain Object,并且向外提供一个接口还是多个接口访问Domain Object的问题。 从这个问题我想到了关于OO中对象和OOP中对象的区别。其实我们很多人对OO中的对象的概念的理解来源于OOP,而不是OO思想本身,而正是这种把OOP的对象当做OO对象的方式制约了我们对OO的理解。 简单的说,OO思想起源于软件设计的一些基本方法,其中最重要的就是模块化、封装和信息隐蔽,这些方法导致了对象的概念,就是封装数据和行为,另外重用方法导致对象的继承概念,而另外的一些概念如多态,接口则完全是某些语言的特性(如静态语言有多态的概念,而对动态语言则不需要),而非OO本身的特性。所以说,从本质上来说,OO中的对象就是对数据和行为的封装。 我们再来看OOP,其实OOP中的所谓的类是对OO中的对象的一种实现,它和OO中的类并不是完全一一对应的关系。同样我们可以使用非OOP语言来实现OO中的对象,只要我们能够很好的对对象的数据和行为做很好的封装。只是一般来说,使用OOP语言进行封装比使用非OOP语言进行封装要容易的多而已。 我个人觉得,OO中的对象和语言实现之间有这么几种关系: 1. OO中的对象不一定和OOP中的对象一一对应,很多时候需要一组OOP中的对象来实现OO中的对象。 2. 用任何语言实现OO中的对象,单靠语言本身的特性是不完整的,还需要在语言之外进行特定的约定,即使对于OOP也是如此。 3. 对于传统的非OOP语言,通过增加一些约定,也可以实现OO中的对象。 对于第一点,上面所说的Domain Object就是一个典型的例子。 对于第二点,我们来举一个不是很恰当的例子来说明: public class Rectangle { private int width; private int height; public Rectangle(int width, int height) { this.width = width; this.height = height; } public int getWidth() { return width; } public int getHeight() { return height; } public int getArea() { return width * height; } } 表明上看,这个类对面积的计算封装很好,其他类只能通过该类的public方法进行访问,但是如果我们对该类的用法没有很好的约定,那么如果其他的类中充斥着这样的代码你会怎么想: int area = rect.getWidth() * rect.getHeight(); 显然,由于没有很好的约定,使用者破坏了对面积计算的封装特性,如果有一天你要改变面积的计算方法(当然这是不可能的,所以说这时一个不恰当的例子)的话,你将无能为力。当然,如果你在事先约定所以计算面积的方法都必须使用getArea方法就可以避免破坏封装的情况。 再看第三点,这里有一个非常典型的例子。使用过C语言的人一定都知道进行文件操作的时候我们使用标准IO库(stdio.h),而操作这些文件我们一般需要FILE结构和一些API,如fopen,fclose,fread,fwrite,其实单从封装的角度来说,FILE结构和这些函数就是典型的OO中的对象。通过俗称的约定,没有人会去直接操纵FILE结构中的成员(实际上,很少有人去看这个结构中究竟有什么内容),这就是所谓的数据封装,另外没有人关系那些函数的实现,这就是行为的封装。它们和一般的OOP之间的区别只是形式上的,用fopen来创建FILE对象,而不是new,用fclose对象来销毁FILE对象,而不是delete,用传入FILE指针作为参数来调用方法,而不是通过"."或者"->"。 总之一句话,OO中的对象可以通过各种方式来实现,可以使用OOP中的类,也可以使用OOP中的多个类,甚至可以不使用OOP中的特性(如果不使用extends的方式来实现继承),另外通过语言来实现的对象的封装是不完备的,你需要使用额外的约定。 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |