曾经有一段时间,论坛上对于Domain Object的实现争论不已,这包括:
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的方式来实现继承),另外通过语言来实现的对象的封装是不完备的,你需要使用额外的约定。
分享到:
相关推荐
无监督领域适应(Unsupervised Domain Adaptation,UDA)是机器学习和计算机视觉领域中的一个重要研究方向,特别是对于目标检测任务。随着深度学习技术的发展,精确且高效的模型已经被广泛应用于诸如物体分类、语义...
Unsupervised Domain Adaption of Object Detectors A Survey.zip
- **面向对象语言(OO Languages)**:介绍了常用的面向对象编程语言的特点和适用场景,如Java、C#等。 - **数据库(Database)**:讨论了面向对象系统与数据库之间的集成问题,包括对象-关系映射(ORM)、数据持久化等...
A Survey on Deep Domain Adaptation and Tiny Object Detection Challenges, Techniques and Datasets.pdf
深度领域适应(Deep Domain Adaptation, DDA)与微小物体检测(Tiny Object Detection)是当前计算机视觉领域中的两个重要研究方向。这篇论文的标题暗示了作者将对这两个主题进行深入探讨,包括面临的挑战、技术手段...
在面向对象的分析(Object-Oriented Analysis,简称OOA)和设计(Object-Oriented Design,简称OOD)中,我们将现实世界问题通过OO方法转换为软件解决方案。这个过程通常涉及如下几个步骤: 1. 需求收集:获取用户...
用于两个domain对象的拷贝,支持字段自动覆盖,选择性覆盖,选择性字段拷贝,作用:当你有多个domain对象都需要生成另外的同一个domain对象的时候这个方法就很有用了,或许存在BUG,欢迎指出
对象模型(Object Model)在DDD中占据重要地位,通过实体(Entities)、值对象(Value Objects)和领域服务(Domain Services)构建。实体是拥有唯一标识且生命周期贯穿的应用对象,而值对象则是描述实体属性的不可...
### 详细介绍ApplicationDomain和SecurityDomain #### 一、概述 在深入探讨ApplicationDomain和SecurityDomain之前,我们首先明确这两个概念的基本定义及其在Flash环境中的重要性。ApplicationDomain和Security...
- **领域模型(Domain Model)**:是对领域中的概念、规则和关系进行建模,形成一种可以被软件实现的语言。 - **界限上下文(Bounded Context)**:是领域模型的边界,在这个边界之内,语言和概念是一致的。界限上...
标题《2019 A Robust Learning Approach to Domain Adaptive Object Detection》和描述中的“域适应”以及“目标检测”指示了本文重点讨论的是计算机视觉领域中的一个核心问题——如何让对象检测模型适应新的、未知...
### 深入理解ApplicationDomain和SecurityDomain #### 安全域(Security Domain)与应用程序域(Application Domain)概述 安全域与应用程序域是Flash Player中两种重要的沙箱概念,它们帮助开发者理解如何管理和...
关系数据库语言SQL是数据库管理系统中应用最广泛的语言之一,是实现数据存储、查询、更新和管理的重要工具。SQL语言的发展历史悠久,它的原型可追溯至1970年代。E.F. Codd在1970年提出了关系模型,IBM公司基于这个...
它基于Object Pascal编程语言,并且以其高效的编译器和直观的可视化设计工具而闻名。Delphi的源代码组织结构通常包括一系列的单元(Units),每个单元都包含特定的功能或类库,这样的设计有利于代码重用和模块化开发...
.NET框架与C#语言结合应用领域驱动设计(Domain-driven Design, DDD)是现代软件开发中的一个重要实践。DDD旨在通过将复杂的业务逻辑集中在核心领域模型上,提高软件系统的可读性、可维护性和可扩展性。本章节我们将...