企业应用架构模式
企业应用架构三层结构一个典型的企业应用按照层级进行划分一般可以分成三个层次:表现层、领域层和数据源层。其中领域层集中了企业应用主要的业务逻辑和规则,是最复杂易变的部分。有三种主要的模式来处理领域逻辑:事务脚本、领域模型以及表模块l 事务脚本:使用过程来组织业务逻辑,每个过程处理来自表现层的单个请求。适用于业务逻辑简单的小型系统l 领域模型:以面向对象的方式建模领域逻辑,对复杂业务建模提供了较好的扩展性和可维护性l 表模块:针对数据表来组织领域逻辑,主要操作的数据结构是记录集,是.net平台最常用的方式;表模块与领域模型的实体对象的关键区别在于它本身没有标识符来标出它所代表的实体对象服务层处理领域逻辑的常见方法是将领域层再细分成两层。服务层独立出来,置于底层的领域模型或者表模块之上。通常只有使用领域模型或者表模块时才会这样细分,因为仅使用事务脚本的领域层并不复杂,没有必要再单独设服务层。表现逻辑与领域层的交互完全通过服务层,就好象应用程序的API一样。在提供一个清晰API的同时,服务层也是放置事务控制和安全等功能的好场所。这样做可以使你获得一个简单的、包含了服务层所有方法并描述了其事务和安全特征的模型。领域层映射到数据源层数据源层可以是文件系统,可以是内存,可以是数据库,只要能提供数据存储功能的都可以成为数据源层;最主要的数据源是关系型数据库,由于领域模型主要的理念是面向对象,而关系型数据库的主要理念是关联的二维表,两者之间存在着概念上的差异,当处理领域模型到数据源层的映射时就有许多问题,主要表现在架构方面和行为方面l 架构问题:对象和表如何映射,如何处理继承关系,对象间的引用如何映射为表之间的关联l 行为问题:对象何时加载,如何跟踪对象属性变化,对象何时保存,如何保证一条记录只有一个对象与之对应,当修改对象的属性并将其保存回数据库时如何保证数据库状态的一致性(同步),如何定义对象的查询成熟的模式数据源架构模式1. 表数据入口充当数据库表访问入口的对象,一个实例处理表中所有的行。表数据入口包含了用于访问单个表或视图的所有SQL,如选择,插入,更新,删除等,其他代码调用它的方法来实现所有与数据库的交互2. 行数据入口充当数据源中单条记录入口的对象。每行一个实例。行数据入口提供了看起来像记录结构中记录的对象,但可以用编程语言的常规机制访问它。所有对数据源的访问细节都隐藏在这个接口之后。使用行数据入口要面对的问题是:在哪里存放产生该模式的查找操作。可以选择静态查找方法,但是它不支持需要为不同数据源提供不同查找方法的多态。在此情况下有必要设置单独的查找对象,这样关系数据库中的每张表都有一个查找方法和一个入口来获得结果3. 活动记录一个对象,它包装数据库表或视图中某一行,封装数据库访问,并在这些数据上增加了领域逻辑。活动记录与行数据入口十分类似。二者的主要差别是行数据入口仅有数据库访问而活动记录既有数据源逻辑又有领域逻辑。由于活动记录和数据库间的紧耦合,在这个模式中常用静态查找方法。但也没有理由说明不能把查找方法分离为一个单独的类4. 数据映射器在保持对象和数据库彼此独立的情况下,在二者之间移动数据的一个映射器层。对象-关系行为模式1. 工作单元维护受业务事务影响的对象列表,并协调变化的写入和并发问题的解决。从数据库中存取数据时,记录所修改的内容是非常重要的;否则,那些改变的数据将不会被写回到数据库中。同样,必须插入创建的新对象和移除已删除的对象。可以在每次修改对象模型时对数据库进行相应修改,但这样会产生大量规模很小的数据库调用,从而导致速度变慢。而且这样做还需要有一个对整个交互过程都开放的事务,这个是不符合实际的;如果还要记录读过的对象以避免不一致读,那么情况会更复杂。工作单元记录在业务事务过程中对数据库有影响的所有变化。操作结束后,作为一种结果,工作单元了解所有需要对数据库做的改变。工作单元的关键是在提交的时候,它决定做什么。它需要打开一个事务,做所有的并发检查(使用悲观离线锁或者乐观离线锁)并向数据库写入所作的修改。工作单元可以提供的另外两项重要功能是:当数据库使用引用完整性时用它来保证更新的顺序;处理批量更新。2. 标识映射通过在映射中保存每个已经加载的对象,确保每个对象只加载一次。当要访问对象的时候,通过映射来查找他们。如果同一条记录被加载到两个不同的对象中,会导致数据更新错误,并且数据重复也会引起性能问题。标识映射记录在一个业务事务中从数据库读出的所有对象。如论什么时候要用一个对象,先检查标识映射,看需要的对象是否已在其中。标识映射同时可以作为数据库记录的高速缓存。根据对象数量和数据多少,标识映射可以将只读对象和可更新对象分开映射,提高查询性能。3. 延迟加载一个对象,虽然它不包含所需要的所有数据,但是知道怎么获取这些数据。当把数据从数据库加载到内存中时,可以把对象和其相关的所有对象一起加载进来,但如果相关对象很多,并且不是都被本次业务过程需要时,冗余数据的加载会严重影响系统的性能。延迟加载会在加载对象的时候只加载对象的一个代理,当真正需要数据的时候,代理类才去从数据库加载数据。对象-关系结构模式1. 标识域为了在内存对象和数据库行之间维护标识而在对象内保存的一个数据库标识域关系数据库通过键尤其是主键来区分数据行,对象通过内存位置来区分,通过在对象中设置标识域来将内存对象和数据行联系起来标识域的概念简单,但有几个比较复杂的问题需要处理:选择键:有业务意义的键/无业务意义的键,最好选择无业务意义的键简单键/组合键,如果选择组合键,键类必须提供Equal方法新键值的产生:数据库产生、GUID、自定义2. 外键映射把对象间的关联映射到表间的外键引用对象可以通过对象引用来相互直接访问,要将这些对象保存到数据库中,对象间的关系也必须保存到数据库中;而且对象很容易能保持到其他对象的引用集合,但这种结构违反了关系数据库的第一范式。外键映射将对象间的引用映射到数据库的外键对象间的关联是正向引用,即父对象保存到子对象的引用,而表间的关联是反向引用,即子表保存到父表的外键,这种不一致的方向在级联更新的时候需要特别处理,有三种方法可以选择:1) 在保存父对象的时候,先删除当前父对象的所有子对象,然后再将子对象集合保存2) 在子对象中添加一个到父对象的引用,将关联变为双向3) 在保存父对象的时候,比较集合中的子对象和数据库中子对象,对差别元素进行处理考虑到效率和易用性,第二种方法是比较好的方法3. 关联表映射把关联保存为一个表,带有指向(由关联所连接的)表的外键关系数据库中多对多关联的处理方式是增加一个关联表,表中每一行保存两个对象间的一个关联;对象间的多对多关联不是通过增加一个对象,而是通过对象中的集合类型的子属性的相互引用这种多对多的映射在加载和保存时,为了提高效率,可以采取联表(join)或者分次操作的方式,很多情况下采用延迟加载的方式避免无用的大数据量查询4. 依赖映射让一个类为部分类执行数据库映射5. 嵌入值把一个对象映射成另一个对象表的若干字段6. 单表继承将类的继承层次表示为一个单表,表中的各列代表不同类中的所有域7. 类表继承用每个类对应一个表来表示类的继承层次8. 具体表继承用每个具体类对应一个表来表示类的继承层次对象-关系元数据映射模式1. 元数据映射在元数据中保持关系-对象映射的详细信息2. 查询对象描述一次数据库查询的对象3. 资源库协调领域和数据映射层,利用类似于集合的接口来访问领域对象