1.- 领域
本节描述了领域逻辑层的架构和设计领域层时需要考虑的重要准则。 领域层负责展示业务,业务流程的状态和领域规则的实现。也应该包括反映业务流程的状态,甚至
当技术存储的细节交给较低层的基础设施(仓储库等)时。 ”领域模型“层是软件的核心。
该层的足见实现了系统的核心功能并封装了所有相关的业务逻辑(在DDD术语中通常叫领域逻辑)。一般的,领域层通常包含实现领域逻辑的类,也可以实现动态业务规则的系统等。按照领域驱动设计的架构模式,该层必须对数据持久化细节透明。这些持久化任务应该由基础结构层完成。实现域逻辑层的主要原因是区分并清楚地把领域规则的行为(领域模型的职责)和持久化实现分开。这样, 通过区分应用领域,我们将大幅提高系统的可维护性,甚至可以替换较低的层而对应用的其它部分影响最小。在本指南中每一章,都会用两种方法展示。第一是逻辑层面上的,可以使用任何技术和语言,下面是技术实现层面,我们会展示如何开发该层,尤其是使用.NET 4.0的技术。
2.- 领域层:逻辑设计和架构
本章由领域逻辑层设计以及领域层功能实现的部分组成。也包括了该层内的典型关注点比如安全性,缓存,异常处理,日志,验证。
该图中展示了“多层面向领域架构”中的领域模型层位置。
2.1.- 示例应用:示例领域模型的业务需求 在对层的细节设计之前,我们想引入一个会按照面向领域设计模式设计的故事情节,会在稍后实现(见在CODEPLEX的示例应用)。注意:
下面我们定义了废材简单的业务需求。这些都是非常简单的,尤其在银行的领域。这事因为示例应用的主要目的是关注架构方面和设计,而不是设计和实现一个真是的完整应用。 领域需求的最初细节,在功能层面通过领域专家的讨论得出: 1.- 需要一个客户和订单的管理应用。需要有一个和公司的银行相关的模块,进行客户的转账和其它操作。 2.- 需要灵活的查询客户列表。对客户的操作需要可以进行灵活的查询;可以按照姓名的一部分查询,以后可以通过其它属性查询。通过用户订单的状态查询也是非常有用的。这些查询的结果需要是客户列表即可。 3.- 需要有指定客户的订单列表。需要显示每个订单的总价,订单的日期。 4.- 一个订单可以有多个订单项。每个订单项是一个包括产品和产品数量的明细。 5.- 可以检测并发冲突。
IT部门告诉我们,可以接受的甚至建议使用“乐观并发控制”。例如,考虑这样的场景,一个用户试图更新他早些时候获取的数据,但是其它用户在第一个用户获取数据后修改了数据库的原始数据。这种情况,当第一个用户试图更新数据时,这个冲突需要检测到(原始数据已更改,有可能保存时丢失数据)。只考虑会引起不一致的冲突。 6.- 一个订单的总值不能少于6美元,超过100万美元。 7.- 每个订单和客户都应该有一个友好的编号。编号应该容易辨认,可写并且容易记住,可以用来搜索用户/订单。如果有必要,应用可以管理更多复杂的ID ,但对最终用户是透明的。 8.- 一个订单总是属于一个客户;一个订单项总是属于一个订单。不能有不属于一个用户的订单,也不能有不属于订单的订单项。 9.- 银行的操作可以和客户和订单模块独立。应该提供一个简单的视图,例如现有帐户列表相关数据(余额,账户数量等),也可以在这些账户中提供简单的银行转账操作。 10.-银行转帐的实际实现应在一个原子操作中完成。因此,应该是一个原子事务。 11.-账户在业务层面有锁住/解锁状态。应用的管理员可以锁住/解锁任何账户。 12.-如果一个账户是锁住,不能进行任何的操作。如果有试图对锁住账户进行操作,应用应该发现并通知用户,告知用户不能操作的原因。 13.-(示例的简化)目的是在功能和数据设计层面进行简单,为了清楚的展示和理解架构,所以优先简化逻辑实体和数据库设计。例如,一个用户的组织和地址合并在同一个逻辑实体甚至是同一张表,但这并不是最好的设计。然而,本例的目标是最大简化应用的功能。实际上,该示例应用准备展示架构的最佳实践,而不是在数据库设计逻辑和逻辑上展示。所以应用中这些特征被简化了: - 一个客户/公司只有一个联系人。 - 一个客户/公司只有一个地址。 根据这些规范,我们会确定示例的元素例如实体,仓储库,服务等等,就像我们重温架构的不同元素。