构建面向对象软件系统框架.doc

上传人:牧羊曲112 文档编号:4265294 上传时间:2023-04-12 格式:DOC 页数:145 大小:4.68MB
返回 下载 相关 举报
构建面向对象软件系统框架.doc_第1页
第1页 / 共145页
构建面向对象软件系统框架.doc_第2页
第2页 / 共145页
构建面向对象软件系统框架.doc_第3页
第3页 / 共145页
构建面向对象软件系统框架.doc_第4页
第4页 / 共145页
构建面向对象软件系统框架.doc_第5页
第5页 / 共145页
点击查看更多>>
资源描述

《构建面向对象软件系统框架.doc》由会员分享,可在线阅读,更多相关《构建面向对象软件系统框架.doc(145页珍藏版)》请在三一办公上搜索。

1、构建面向对象的应用软件系统框架孙亚民目录第一部分综述4第1章本书会讨论什么内容5第2章系统的分层结构821简述822设计的原则和评判标准923应用服务层的内容1024数据实体的表示1125数据的存取方式1526业务逻辑的处理1827业务服务的提供2028层的部署和层间交互2029剪裁和取舍21210小结21第二部分应用服务层的设计23第3章数据和对象2431数据的形态2432对象/关系型映射2633对象的状态28Transient28Persistent-new29Persistent-dirty29Persistent-clean29Persistent-deleted29第4章O/R Ma

2、pping的一般做法31第5章设计一个O/R Mapping框架4051封装数据库访问层4052设计映射4853 对继承的支持5554设计对象操纵框架6155实现对象操纵框架66第6章面向方面编程7161 AOP概念7162 Websharp AOP的使用73621使用AOP实现松散耦合73622使用AOP组合两个业务逻辑7663 Websharp AOP的实现76631 AspectObject抽象类78632 IAspect接口78633 AspectManagedAttribute78634 定义AspectProxy类80635 其他一些辅助类80636 配置文件8064 关于AOP和

3、过滤器8165 小结82第7章接口83第8章事务处理868.1 事务的基本概念868.2 实际开发中可用的事务处理方式88第9章性能优化101第三部分用户界面层设计102第10章界面层的功能划分103第11章界面设计模式10411.1 MVC模式10411.2 页面控制器107第12章动态代码生成和编译技术10812.1 Emit10812.2 CodeDom108第13章远程过程访问的客户端整合111Web Service111.Net Remoting112Websharp Service Locator的主要接口114Websharp Service Locator的配置文件114如何使

4、用Websharp Service Locator116LocalAssemblyLocator 的Hello World例子116Hello World 的WebServiceLocator例子118Websharp Service Locator的实现120目前的进展120将来的目标120小结120第14章智能客户端122小结128第四部分系统建模过程129第15章简述130第16章用例模型系统需求的获取131第17章分析模型开发者的视野135第18章系统设计实现方案141第一部分综述第1章 本书会讨论什么内容从软件工程说起。提起这个概念,往往令人想起CMM、RUP、印度模式等。管理的因素

5、,在软件开发过程中起着非常重要的作用,然而,软件工程并非只指软件开发的管理工作,而是一个范围很广的综合性学科。在软件工程中,大约一半的内容是专业性很强的,涉及到软件分析、设计甚至编码的技术。所谓的结构化、面向对象,都在软件工程的范畴内。“软件工程范围极为广泛。软件工程的某些方面属于数学或计算机科学,其他方面可归入经济学、管理学或心理学中。”软件业一直在探讨,如何使软件实现如同传统产业一样的大规模生产。软件工程的提出,便是为了实现这个愿望。然而,虽然软件工程至今已经有了很大的发展,软件的大规模工业化生产仍然没有实现。原因何在?从软件的本质属性来说,软件的复杂性是软件的本质属性,在这个属性没有改变

6、之前,软件便不会实现同传统产业一样的工厂化生产。从软件生产的介质来说,传统产业生产都是有形的物质产品,人的生产活动都受制于生产资料这些物质介质;然而,软件生产的介质,却是无形的人类的思维。物质资料的生产,受制于物质本身的属性,不容易为人类的思维所左右,并且容易被大量复制,这使得工业化大生成为可能。而人类的思维,却是如此的容易变化,更关键的是不能被复制,甚至同一个人,不同时期思维的复制都不可能,这使得软件这个纯粹依赖人的思维活动的生产实现大规模工业化生产是如此的困难。实际上,不仅仅是软件产业,凡是主要生产介质是人本身的活动的产业,都很难实现工业化生产,如咨询、演艺等。从生产过程来看,对于传统产业

7、来说,产品的设计和生产是分开的。在设计阶段,主要的工作是人的思维,因此,在这个阶段,同软件一样,不是批量生产的。而在生产阶段,主要的对象便是物质资料,并且一切标准已经制定,只需要在流水线上大量复制。对于传统产业来说,设计和生产的界限是如此的明确,并且,生产和设计的比重是如此的悬殊。然而,对于软件产业来说,软件的生产过程便是设计的过程,纯粹的生产过程几乎不存在(或许,光盘的复制算是),这使得软件的生产形态同传统产业必然存在区别。对于软件的开发过程来说,从业务模型、需求分析、系统架构、系统分析和设计、到最后代码实现,越往前,抽象层次越高,可控性越小,越往后,越接近实际,可控性越大,因此,在软件开发

8、中,核心团队的作用是如此巨大,一个软件产品的成败,核心团队的核心人员的作用在很大程度上是决定性的。对于软件开发来说,如果软件开发要实现工业化生产,必定是从后向前推进,从编码开始。印度模式或许给出了这么一个例子。因此,我们在软件工程的路上,只是在不断的向工程化的目标迈进,但是,要达到这个目标,可能会花很长的时间。技术上的每一次进步,都使我们向这个目标迈进了一步。在软件工程的发展过程中,技术进步起了非常大,甚至可以说是决定性的作用。随着采用的技术的不同,所采用的管理方法也在不断变化。软件工程技术的很多方面,也是为管理做准备的。优秀的软件开发技术的采用,能够弥补我们在工程化方面的不足,从而使得软件开

9、发更加可控,软件质量更加有保障。本书不准备讨论软件工程过程的问题,而只是对软件工程中软件技术的一个方面系统框架设计,做一些探讨。现在,很多开发人员都已经意识到这很重要的一点,那就是,在开发一个应用软件系统的时候,一个好的系统框架是非常重要的。从底层开始构建应用程序,是一件吃力不讨好的事情,而没有框架的应用程序,则很难想象会是一个好的应用程序。除了对于开发的直接帮助,一个好的框架对于公司的知识管理也是非常有意义的。想象一下,我们经常在讨论,现在是一个知识经济的时代,尤其对于软件公司来说,知识(拥有这些知识的员工)就是公司最大的财富。那么,怎么来进行有效的知识管理呢?首先,应当明确,知识管理,一个

10、重要的目的,就是要把员工对公司最重要的知识沉淀下来。公司的每个员工头脑里都有很多的知识,这些知识对于员工来说是很重要的,但是其重要性同公司并不是完全一致的。某些知识,对于某个员工来说是最重要的,但是对于公司可能并不需要。知识管理需要做的,是把员工对公司最重要的知识累积起来。其次,知识管理必须有一个载体。如果知识管理没有载体,那么,公司的知识就存在于员工的头脑之中,一旦这个员工离职,那么,知识也就离去了,没有办法沉淀。如果只是把公司做过的项目的文档作为载体,那么,这个载体就过于零碎了。实际上,如果公司有一个统一的框架,那么,这个框架就是一个很好的知识管理的载体。因为,这个框架,必定是集中了公司所

11、有软件项目的共同点的,集中了对于公司最重要的知识的精华,能够为公司所有的项目服务。另外,随着框架的不断被使用,框架本身也会随之升级优化。对于一个新成员的加入,他只要理解掌握了这个框架,就可以很好的融入团队中来;而人员的离去,也已经把自己对公司最重要的知识留在了这个框架中。可以说,在这里,框架承担了一个知识管理平台的作用。一个最好的例子就是微软的Windows。这是微软所有知识的最集中的平台。软件,从本质上来说,就是现实世界在计算机中的模拟。在考虑应用软件系统架构的时候,实际上,考虑的问题主要在于:处理什么?怎么处理?如何使用?因此,应用软件系统,需要关注的方面,概括起来,主要包括以下三个大类:

12、1、 处理的对象,也就是数据。2、 处理的方式,也就是我们的系统如何来处理系统的逻辑。3、 如何进行交互,这个交互包括用户(使用者),以及外部系统。在应用软件系统中,数据是处理的基本对象,程序总是以一定的数据结构来表现数据,并且,在使用面向对象语言开发的系统中,数据总是以类和对象的形式表现出来。另外一方面,数据总是需要存储,对于大部分应用软件系统来说,通常会采用关系型数据库来保存数据。这样,由于数据在程序和数据库中表现格式的不一致,就必然要求在两者之间进行映射。这个映射,在面向对象设计语言和关系型数据库之间,通常称为对象/关系型映射,即O/R Mapping。目前,在O/R Mapping部分

13、,在Java平台下,已经有多种可以选择的方案,例如J2EE架构中的Entity Bean,轻量级的JDO,以及开源项目的Hibernate等,由于微软的.Net框架推出时间不长,成熟的O/R Mapping框架并不多见。O/R Mapping框架的选择或者设计是构建应用软件系统的最基本的工作。本书将讨论构建O/R Mapping框架的一些基本理论、概念和方法。系统的业务逻辑处理,是应用软件系统的核心部分,如何合理的构建业务逻辑、如何提供业务逻辑层的服务,以及表现层如何访问业务逻辑提供的功能,也是应用软件系统需要重点关注的问题。在这个方面,业界已经发展了很多可供选择的范式,如契约式设计、SOA架

14、构(面向服务的架构)等。这些方法指明了设计的方向,同时也需要我们在实际开发中加以应用。在业务逻辑确定后,随后而来的问题就是,如何向客户端来提供业务逻辑服务,或者说,客户端如何访问这些服务。在多层应用软件系统中,客户端和业务逻辑在物理上可能存在于不同的机器上,也可能存在于同一台机器,但至少,在逻辑上,是存在于两个不同部分,这就涉及到一个问题:这两个层之间如何进行通信?还会涉及到远程过程调用的问题。当然,现在我们已经有多种技术来远程过程调用,包括Webservice、.Net Remoting、Corba、甚至EJB等。如此多的实现技术,带来的很大的灵活性,但同时也带来了问题,其中一个就是,有多少

15、种服务端技术,就得有多少种相应的客户端访问技术。甚至,在某些分布式应用系统中,应用逻辑使用不同的技术开发,存在于不同的机器上,有的存在于客户机本机,有的使用.Net Remoting开发,存在于局域网内,有的使用因特网上的Web Service,有的时候,我们希望相同的业务逻辑能够支持不同的客户端。在这种情况下,我们需要一个一致的服务访问编程模型,以统合不同的服务访问模式,简化系统的开发和部署。一个统一的远程过程调用框架的前景是如此的诱人,以至于每一种方法都试图一统天下,但出于种种原因,最终都没有一家能够做到,最新的Web Service就力图做到这一点。实际上,每一种方法的出现,最终都会带来

16、一个副作用,那就是,可供选择的多了一点,混乱也就又多了一点。在实际的开发过程中,我们也需要一个统一的访问方式来解决这个问题。本书将讨论一些可用的方案。为了更加清晰的进行表述,文章会附加一些程序代码。因为在讲到具体的技术的时候,本书会对各种可用的技术进行比较,因此,本书的代码可能会使用不同的语言,通常是Java和C#,不过,在给出代码的时候,一般都会指明所用的语言。在大部分情况下,如果不说明具体的语言,那么就是C#(因为我比较喜欢这门语言)。因为Java和C#的语法是如此的相像,我想,对有经验的程序员来说,这应该不会造成阅读上的麻烦。第2章 系统的分层结构21简述我们在解决一个复杂的问题的时候,

17、通常使用的一个技巧就是分解,把复杂的问题分解成为若干个简单的问题,逐步地、分别地解决这几个小问题,最后就把整个问题解决掉。在设计一个复杂的软件系统的时候,同样的,为了简化问题,我们也通常使用的一个技术就是分层,每个层完成自身的功能,最后,所有的层整合起来构成一个完整的系统。分层是计算机技术中的常用方法,一个典型的例子就是TCP/IP技术的OSI七层模型。在应用软件开发中,典型的就是N层应用软件模型。N层的应用软件系统,由于其众多的优点,已经成为典型的软件系统架构,也已经为广大开发人员所熟知。在一个典型的三层应用软件系统中,应用系统通常被划分成以下三个层次:数据库层、应用服务层和用户界面层。如下

18、图(图2.1)所示:图2.1其中,应用服务层集中了系统的业务逻辑的处理,因此,可以说是应用软件系统中的核心部分。软件系统的健壮性、灵活性、可重用性、可升级性和可维护性,在很大程度上取决于应用服务层的设计。因此,如何构建一个良好架构的应用服务层,是应用软件开发者需要着重解决的问题。 为了使应用服务层的设计达到最好的效果,我们通常还需要对应用服务层作进一步的职能分析和层次细分。很多开发者在构建应用服务层的时候,把数据库操纵、业务逻辑处理甚至界面显示夹杂在一起,或者,把业务逻辑处理等同于数据库操纵,等等,这些,都是有缺陷的做法。我们将就在这个方面进行设计时可采用的方案进行一些探讨。 在一个分布式应用

19、系统中,整个系统会部署在不同的物理设备上,如上面所示的三层体系,用户界面和应用服务器可能在不同的设备上,这就涉及到不同机器之间的通信问题,也就是层间的通信和交互问题。我们已经有了很多可以用于分布式远程访问的技术,如CORBA,在Java平台上,我们还有Java RMI、EJB,在Windows平台上,从DCOM到COM+,再到.Net下的Web Service和.Net Remoting等。如何选用合适的远程访问技术,也是我们在系统框架中需要考虑的问题。6为了使讨论更具有针对性,本文也会讨论一些比较流行的系统架构,例如J2EE架构,以及JDO,然后,我们会讨论Websharp在这个方面的一些设

20、计理念。22设计的原则和评判标准 同软件工程的原则一样,应用服务层的设计,必须遵循的最重要的原则就是高内聚和低耦合7。软件分层的本来目的,就是提高软件的可维护性和可重用性,而高内聚和低耦合正是达成这一目标必须遵循的原则。尽量降低系统各个部分之间的耦合度,是应用服务层设计中需要重点考虑的问题。内聚和耦合,包含了横向和纵向的关系。功能内聚和数据耦合,是我们需要达成的目标。横向的内聚和耦合,通常体现在系统的各个模块、类之间的关系,而纵向的耦合,体现在系统的各个层次之间的关系。 系统的框架,通常包含了一系列规范、约定和支撑类库、服务。 对于如何判断一个软件的系统框架的优劣,笔者认为,可以从以下几个方面

21、来评判: 系统的内聚和耦合度 这是保证一个系统的架构是否符合软件工程原则的首要标准。 层次的清晰和简洁性 系统每个部分完成功能和目标必须是明确的,同样的功能,应该只在一个地方实现。如果某个功能可以在系统不同的地方实现,那么,将会给后来的开发和维护带来问题。 系统应该简单明了,过于复杂的系统架构,会带来不必要的成本和维护难度。在尽可能的情况下,一个部分应该完成一个单独并且完整的功能。 易于实现性 如果系统架构的实现非常困难,甚至超出团队现有的技术能力,那么,团队不得不花很多的精力用于架构的开发,这对于整个项目来说,可能会得不偿失。简单就是美。 可升级和可扩充性 一个系统框架,受设计时技术条件的限

22、制,或者设计者本人对系统认识的局限,可能不会考虑到今后所有的变化。但是,系统必须为将来可能的变化做好准备,能够在今后,在目前已有的基础上进行演进,但不会影响原有的应用。接口技术,是在这个方面普遍应用的技巧。 是否有利于团队合作开发 一个好的系统架构,不仅仅只是从技术的角度来看,而且,它还应该适用于团队开发模型,可以方便一个开发团队中各个不同角色的互相协作。例如,将Web页面和业务逻辑组件分开,可是使页面设计人员和程序员的工作分开来同步进行而不会互相影响。 性能 性能对于软件系统来说是很重要的,但是,有的时候,为了能让系统得到更大的灵活性,可能不得不在性能和其他方面取得平衡。另外一个方面,由于硬

23、件技术的飞速发展和价格的下降,性能的问题往往可以通过使用使用更好的硬件来获得提升。 23应用服务层的内容 应用服务层,通常也被称为业务逻辑层,因为这一层,是应用软件系统业务逻辑处理集中的部分。然而,我将这一层称为应用服务层,而不称业务逻辑层,因为,这一层需要处理的不仅仅是业务逻辑,还包含了其他方面的内容。 从完整的角度来说,应用服务层需要处理以下内容: 数据的表示方式 数据,是软件处理的对象。从某种程度上来说,软件,就是数据结构加算法的说法,是有一定意义的。在面向对象的系统中,数据是用类来表示的,代表了现实世界实体对象在软件系统中的抽象。考虑所谓的MVC模式,这个部分的类属于M-实体类的范畴。

24、由于应用软件通常会使用数据库,数据库中的数据,可以看成是对象的持久化保存。由于数据库一般是关系型的,因此,这个部分,还需要考虑类(对象)同关系型数据的映射,即通常所说的O-R MAP问题。 数据的存取方式 如同上述所说,软件系统处理的实体对象数据需要持久化保存数据库中,因此,我们必须处理系统同数据库的交互,以及数据的存取和转换方式的问题。 业务逻辑的组织方式 在面向对象的系统中,业务逻辑表现为对象之间的交互。有了上述的实体对象,以及对象的保存策略,就可以将这些对象组合起来,编写我们的业务逻辑处理程序。在业务逻辑的处理中,必须保证处理的正确性和完整性,这将会涉及到事务处理。通常,我们也会把业务逻

25、辑封装成组件的形式,以得到最大的可重用性。 业务服务的提供方式 在我们完成系统的功能后,如何向客户提供服务,是我们需要考虑的问题。这里的客户,不仅仅是指软件的使用者,也包括调用的界面、其他程序等。例如,在一个基于Web的ASP.Net或JSP系统中,业务逻辑功能的客户便是这些ASP.Net页面或JSP页面。业务逻辑组件应该通过什么方式,直接的,或间接的,向这些客户提供服务,是这一层需要完成的任务。 层的部署和层间交互 对于一个多层的应用软件系统来说,尤其是大型的应用软件系统,通常需要把不同的部分部署在不同的逻辑或物理设备上。特别是一些基于Web的应用软件系统,其部署工作将涉及到Web服务器、组

26、件服务器、数据库服务器等不同的服务设备。在进行应用软件架构的设计的时候,必须考虑各种不同的部署方案。 当系统需要进行分布式访问的时候,如何统一和简化分布式系统的开发,便成了系统框架需要考虑的内容。综上所述,一个完整的基于Web的应用软件系统,其架构可以用图2.2来表示(Websharp的应用软件系统架构):图2.2对于以上各个方面来说,每个问题都可以有很多种策略和方案,但是,在一个系统中,应该尽可能的统一这些策略和方案。也就是说,在一个系统,或者一个项目中,应该统一每个解决每个问题所采用的方法。软件的开发方法是灵活的,可以用不同的方法解决相同的问题,这会诱使开发人员采用他们认为能够表现自己的方

27、法,但是,从整个系统来看,这将会是灾难性的。我们应该尽可能统一,就是,采用统一的数据表示方式、统一的数据存取方式、统一的业务逻辑处理方式等。 下面,将就这些部分的设计策略和可用方案进行一些比较详细的论述。 24数据实体的表示 应用软件系统,从本质上来说,是计算机对现实世界的模拟。现实世界中的实体对象,在软件系统中,表现为需要处理的数据。在面向对象的系统中,这是通过“类和”对象来表示的。 参考著名的“MVC”模式8,类可以分成实体类(M)、控制类(C)、和边界类(V),分别代表了实体对象、控制和界面显示。系统中需要处理的数据,在面向对象的系统中,属于实体类部分。 在考虑数据实体层的设计策略的时候

28、,需要把握以下要点: 一致的数据表示方式。在一个系统中,数据的表示方式必须尽可能统一,同时,在处理单个数据和多个数据的时候,处理方式尽可能一致。 因为数据通常是需要存储到数据库中,因此,良好的映射方法是必需的。 处理好对象的粒度,即所谓的粗粒度对象、细粒度对象。 一般例子 考虑一个现实的例子,一个仓库中的产品(Product),在系统中可以使用如下定义: public class Productpublic string Name; /名称public decimal Price;/价格public int Count;/数量可以按照如下方法使用Product类:Product p=new P

29、roduct(); /处理Product这是一个包含了三个属性的Product类的定义。为了便于说明,在这里,我们尽量将问题简化了。 又例如,一张入库单可以使用如下定义: public class Formpublic string ID; /入库单编号public DateTime AddTime; /入库时间public FormDetail FormDetails; /入库单明细public class FormDetailpublic Product InProduct; /入库产品public int Count; /入库数量对于处理单个对象,通常采用上述的方法,但是,当我们需要处理

30、相同类的一组对象,也就是处理一个对象集合的时候,就会有一些小小的麻烦。 如前所述,我们希望在处理单个对象和对象集合的时候,处理的方式尽量统一,这对于软件开发的意义是很大的。常用的处理对象集合的方法有: 数组表示的方法 例如,上面的例子中当一张入库单包含多条入库单明细的时候采用的方法。为了灵活性,也可以使用容器来,如Java中的Vector或C#的ArrayList(C#)。只是,在处理对象的时候,需要一个类型转换的操作。这个问题,在支持泛型的语言中不会存在,如使用C+的标准库的容器类。 ObjectCollection方法。这个方法同上面的方法类似,不同之处在于,为每个实体类设计一个Colle

31、ction类。例如,可以为FormDetail设计一个FormDetailsCollection类(C#): public class FormDetailsCollection: ArrayListpublic void Add(FormDetail detail)base.Add(detail);public new FormDetail thisint nIndexgetreturn (FormDetail)basenIndex;这么做的好处在于,在操作集合中的对象时,不必进行类型转换的操作。 数据集的表示方法。 采用这种方法,通常是直接把从数据库查询中获取的数据集(Recordset)

32、作为数据处理对象。这种方法在ASP应用程序中是非常常见的做法。这种做法简单,初学者很容易掌握,但是他不是一种面向对象的方法,弊病也很多。 EJB的方法 在J2EE体系中,对实体对象的处理的典型方法是Entity Bean。J2EE中使用Entity Bean来表示数据,以及封装数据的持久化储存(同数据库的交互)。由于Entity Bean比较消耗资源,而且采用的是远程调用的方式来访问,因此,在需要传递大量数据,或者在不同的层次之间传递数据的时候,往往还会采用一些诸如值对象(Value Object)的设计模式来提升性能。关于J2EE中的设计模式的更多内容,可以参考J2EE核心模式一书。 9JD

33、O的方法 相对于J2EE这个昂贵的方法来说,JDO提供了一个相对轻量级的方案。在JDO中,你可以采用一般的做法,编写实体类,然后,通过一些强化器对这些类进行强化,以使其符合JDO的规范,最后,你可以通过PersistenceManager来实现对象的持久化储存。 10无论是EJB还是JDO,在同数据库进行映射的时候,都选用了XML配置文件的方式。这是一种灵活的方式。由于XML强大的表达能力,我们可以很好的用它来描述代码中的实体类和数据库之间的映射关系,并且,不用在代码中进行硬编码,这样,在情况发生变化的时候,有可能只需要修改配置文件,而不用去修改程序的源代码。关于EJB和JDO的配置文件的更多

34、的信息,各位可以参考相关的文档,这里不再赘述了。 然而,使用XML配置文件的方式并不是唯一的方法,在微软提供的一些案例中,如Duwamish示例11,就没有采用这种方式。至于开发人员在开发过程中具体采用哪种方式,是需要根据具体情况进行权衡和取舍的。 Websharp的方法 Websharp在数据的表现上,充分利用了.Net Framework类库中DataSet和特性(Attribute)的功能。我们设计了一个EntityData类,这个类继承了DataSet,并增加了一些属性和方法。在Websharp中,当表示一个实体类的时候,需要定义一个抽象类,这个抽象类继承PersistenceCapa

35、ble。例如,一个Schdule类可以表示如下:TableMap(Schdule,GUID)WebsharpEntityInclude(typeof(Schdule)public abstract class Schdule : PersistenceCapableColumnMap(GUID,DbType.String,)public abstract string GUIDget;set;ColumnMap(UserID,DbType.String,)public abstract string UserIDget;set;ColumnMap(StartTime,DbType.DateTi

36、me)public abstract DateTime StartTimeget;set;ColumnMap(EndTime,DbType.DateTime)public abstract DateTime EndTimeget;set;ColumnMap(Title,DbType.String,)public abstract string Titleget;set;ColumnMap(Description,DbType.String,)public abstract string Descriptionget;set;ColumnMap(RemidTime,DbType.DateTime

37、)public abstract DateTime RemidTimeget;set;ColumnMap(AddTime,DbType.DateTime)public abstract DateTime AddTimeget;set;ColumnMap(Status,DbType.Int16,0)public abstract short Statusget;set;类的TableMap 特性指明了同Schdule实体类相映射的数据库表,以及关键字,ColumnMap特性指明了同某个属性相映射的数据库表字段,以及数据类型和默认值。在实际的应用中,定义了这样一个Schdule抽象类后,要获取一个

38、实体对象,因为Schdule类是抽象的,所以你不可以直接使用new操作来初始化Schdule对象,应当通过如下方式取得:Schdule schdule = EntityManager.CreateObject(typeof(Schdule) as Schdule;EntityManager会即时编译出一个Schdule的实现类,并且返回一个对象。在这种方式下,实体类同数据库表的映射是通过Attribute来实现的。可以使用另外一种方法来表示一个实体类。在这种方式下,需要编写一个XML映射文件,然后,可以使用如下方式取得一个实体对象:EntityData schdule =EntityManag

39、er.GetEntityData(Schdule);然后,可以通过如下方式来访问这个对象的属性: string Title = schduleTitle可以看到,这种方式同传统的方式有点不同。在这种方式下,数据的表现形式只有一个,那就是EntityData。其好处是明显的,不用为每个实体都单独编写一个类,能够大大减少代码的编写量。其缺点也很明显,那就是不能利用编译器类型检测的功能,如果在调用对象的属性的时候,写错了属性的名称,就可能出错,这需要更加仔细的测试工作。但是,这个问题可以通过工具生成代码来解决。 25数据的存取方式 数据存取的目的,是持久化保存对象,以备后来的使用,如查询、修改、统计

40、分析等。存取的对象,可以是数据库、普通文件、XML甚至其他任何方式,只要保证数据能够长久保存,并且,不会受断电、系统重起等因素的影响。在这个部分,最理想的状况,自然是能够支持除了数据库以外的各种类型的存取方式,或者,至少留有接口,能够比较方便的扩充。 因为数据库是最常用,也是最有效的数据存储方法,因此,支持数据库存储是最首先必须支持的。在不同的平台下,有不同的数据库访问的手段。例如,在Java平台下,有JDBC,在Windows平台下,可以使用ADO、ADO.Net等。但是,这些手段还比较接近底层,在实际操纵数据库的时候,需要编写大量的代码,并且,我们还需要通过手工的方式来完成将程序中的面向对

41、象的数据存储到关系型数据库的工作。这么做,自然编程的效率不高,并且非常容易出错。但是,不可否认,这也是一种可以选用的方式。 从另外一个方面来看,由于我们前面已经解决了数据的映射问题,因此,在数据的存取方面是非常有规律的,我们完全可以让这个工作通过框架来执行。这样,我们一方面可以简化很多同数据库交互方面的代码编写工作量,能够减少出现Bug的几率,另一方面,由于框架封装了不同数据库之间的差异,使得我们在编写程序的时候,不用考虑不同数据库之间的差异,而将这个工作交给框架去做,实现软件的后台数据库无关性。 在这个部分,以下两个部分的类会显得特别重要: 对象-关系映射的分析类,能够通过既定的方案完成对象

42、-关系的映射,确定数据存取方案 数据库操纵类:根据映射关系,将数据准确的存储到数据库中,并且封装不同数据库之间的差异。 这个部分的操作过程,可以用图(图2.3)大概的表示如下: 图2.3在J2EE中,这个部分比较典型的就是EntityBean中的CMP。由于在BMP中,同数据库的交互部分需要通过手工编写代码的方式来实现,因此,很难享受到容器带来的便利,只是由于EJB2.0以前的标准,CMP的功能,包括映射能力、实体关系模式等方面的功能比较弱,所以,在很多时候,我们不得不使用BMP。现在,EJB2.0,在这个方面的功能已经非常强大了,我们完全可以享受容器带来的便利,而将大部分精力放在实现更加复杂

43、的业务逻辑方面了。 在JDO中,您同样可以通过PersistenceManager来实现同样的目标,例如,您想把一个Customer对象保存到数据库中,可以采用类似于下面的代码: Schdule schdule=new Schdule();PersistenceManager PM=PMFactory.initialize();Pm.persist(schdule);代码同样非常简明和直观,没有一大堆数据库操纵的代码,也不容易发生差错。 Websharp的方案 同JDO类似,Websharp定义了PersistenceManager接口,这个接口的定义在后面的章节中会给出,这里,我们先看看其使

44、用方式。当我们有了某个实体对象后,需要保存到数据库中的时候,我们可以使用下面的代码来实现:public bool AddSchdule(Schdule schdule)PersistenceManager pm = PersistenceManagerFactory.Instance().CreatePersistenceManager();trypm.PersistNewObject(schdule);return true;catchreturn false;finallypm.Close();在这里,我们不需要关心具体的数据库版本,框架会封装不同数据库之间的差异,保证数据可以正确的存储到

45、不同的数据库中。在这个部分,另外需要注意的是,为了保证数据存储的完整性,应当考虑事务处理的功能。J2EE、JDO和Websharp都支持在数据存储的时候使用事务处理。 在Websharp中,通过Transaction接口,提供了基本的事务处理能力。上面的代码,如果需要使用事务处理,则可以修正如下:public bool AddSchdule(Schdule schdule)if(!CheckSchdule(schdule)return false;PersistenceManager pm = PersistenceManagerFactory.Instance().CreatePersistenceManager();Transaction trans = pm.CurrentTransaction;trans.Begin();trypm.PersistNewObject(schdule);trans.Commit();

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 生活休闲 > 在线阅读


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号