破狼 Blog

Write less got more.

软件架构设计模式简述

在软件开发设计中我们经常会面对业务分析,提取领域问题,从而实现软件架构设计。关于 软件架构设计Martin Fowler在2004出版的《企业应用架构模式》中 概括了四种方式的架构模式。它们分别为事务性脚本,表驱动模式,活动记录模式,领域驱动设计。前两者事务性脚本,表驱动模式作为 面向过程方式架构设计,后两者为面向对象架构设计。它们适合于不同的业务场景,它们也各有长短。

事务脚本模式

事务脚本模式是架构设计中最简单的架构模式,面向过程模式。该模式以用户的操作,UI表现为起点,设计业务组件, 即业务逻辑将直接映射到用户界面的操作。这通常是从表现层逻辑出发,表现层需要什么那么业务层就提供什么, 直到数据层。针对每一个用户的新功能都需要新增一个从UI到关系数据库的分支流程。其适用于逻辑不是 很复杂或者变化不会太大的稳定的应用系统开发。其不需要付出与业务无关的额外代价,并且在现代可见即可得的IDE 结合,能够很快的进行快速应用开发(RAD)。但是这种优势,也是其最大的劣势,程序中充满了IF-else, switch-case之类的逻辑或者大量的static的方法,每个功能都是一个程序分支,这对代码无法重用。 编码不易于维护,对复杂项目和变化需求不适应。

表驱动模式

表驱动模式为每个数据库表定义一个表模块类,包含操作该数据的所有行为方法。作为一个容器,将数据 和行为组织在一起。其对数据的粒度针对于数据表,而非数据行,因此需要以集合或者表(DataTable)传递数据信息。 表驱动模式基于对象但是完全由数据库驱动开发,在业务模型和数据库关系模型显著差异的情况下,应对需求, 并不是那么适合。但是在.net中提供的一些列如强类型DataSet等IDE的辅助下自动生成大量的代码, 也是一个不错的选择,因为部分数据库的操作趋于自动化。表驱动模式没有太过于关注业务逻辑,而是关注数据库 表结构。而业务逻辑和领域问题才是软件核心,所以对于复杂的场景也存在不能很好的胜任。

活动记录模式

活动记录模式是一个以数据库表一行Row为对象,并且对象中包含行为和数据的模式方法。其数据对象 很大程度的接近数据库表结构。在活动记录模式中对象通常也包含架构设计和扩展对象的CRUD(增删改查)的行为,以及数据验证等业 务规则。对于业务不是很复杂,对象关系与关系模型映射不具有很大差异情况,活动记录模式会运用的 很好。活动模式比较简单化设计,在现行的如Linq to sql,ActiveRecord框架, spring JDBC(Active Record),Ruby On Rails之类的框架之下, 将针对问题领域不是太过复杂的中小型项目十分有用,而且能做到快速,并且有较好设计的架构设计和扩展。 但是其模式和数据库表结构的过度的相互依赖,导致若你修改 数据库结构,你不得不同时修改对象以及相关逻辑。如果不能保证数据库关系模型和对象模式的很大程度 的相似这就进入的困境,无法解决对象和数据库结构的映射。

领域驱动设计(DDD)

在我们所述前面的几种架构模式都是在项目开始站在了以数据为中心的角度,而不是业务本身的问题领域。 而领域驱动设计模式是着重关注于系统的业务问题领域,首先开始为领域对象设计。与活动记录模式来说, 领域模型完全反映于问题领域业务概念模型逻辑,与数据库,持久化机制完成独立,其推崇持久化透明(POCO)。 其可以充分利用面向对象设计,不受持久化机制的任何约束。其为完全由业务驱动出来的。但是其最大的优势如上 各个模式一样也是其最大的劣势领域对象模型与关系模型具有天然的阻抗,领域实体对象早晚会需要映射到 持久化机制,有时我们必须等为了这种阻抗而让步。在当前有NHibearnate,EF,Fluent NHibearnate这类 ORM(Object Relation Mapping)框架辅助。

领域驱动设计是Eric Evans于2004年在《领域驱动设计:软件核心复杂性应对之道》 首先提出的,简称DDD.其实际为面向对象分析设计(OOAD)的延伸,利用面向对象思想进行分析设计,对系统逻辑严格 分层,对领域对象的的职责划分。领域逻辑按照职责和内聚的划分在不同的领域对象上,对象不再是单纯的数据载体,而应该 是一个具有行为,逻辑的富对象。

同时领域驱动设计中分层架构也是很重要的一部分,这是分离关注点(SOC)的体现。按照职责对每一层次划分。大体分为 表现层,业务逻辑层,仓储层,领域层,以及基本出设施层。以及后来所倡导的CQRS(读写分离).在层次之间为了应对面向对象设计 所有存在领域模型(DO),然而我们常用的存储却是关系类型(PO),所以还存在ORM(Object Relation Mapping).以及为了更好的 适应UI的表现存在视图对象(VO,有时我们简单VO的存在直接用数据传输对象(DTO)代替),所以存在DTO Mapping,在这里的VO或者DTO,往往 都是一层简单getter,setter的数据载体。

在领域驱动设计中还包含工作单元(UOW)),仓储,值类型,实体,聚合根,领域事件,领域边界,以及领域跟踪一类的概念,关于这些更多的知识 请参考《企业应用架构模式》,以及实现领域驱动设计

最后推荐最新的领域驱动设计书籍资料:此书被DDD鼻祖Eric Evans誉为继其开山之作后,近十年内第一本将DDD落到具体(接地气)的经典书籍。

实现领域驱动设计

Comments