数据源架构模式
Table Data Gateway
-
- 充当数据库表访问入口的对象.一个实例处理一个表中所有的行.
- 在应用逻辑中混杂SQL语句会引起问题.
- 表数据入口包含了用于访问单个表或者视图的所有SQL.其他代码调用它的方法来实现所有与数据库的交互.
- 运行机制
- 其用于数据读写,因此是无状态的.
- 每个方法都将输入参数映射为SQL调用并在数据库连接上执行该语句.
- 从查询返回信息
- 返回简单数据结构,如Map.缺点是破坏了编译时检查.
- 采用额外的数据传输对象.
- 使用时机
- 表数据入口同表模块可以很好地使用.它产生一个记录集数据结构,然后由表模块处理.
- 它特别适合于事务脚本.
- 一般不和领域模型一起使用.
- 表数据入口能够很好滴运行在任何平台上,因为它只是对SQL语句的一种包装.
- 充当数据库表访问入口的对象.一个实例处理一个表中所有的行.
- Row Data Gateway
- 充当数据源中单条记录入口的对象.每行一个实例.
- 其提供了看起来像记录结构中记录的对象.但是可以用编程机制访问的对象.对数据源的访问细节隐藏在接口之后.
- 运行机制
- 它能够实现从数据源类型到内存中类型的任意转换.其尤其适合于事务脚本.
- 一般使用单独的查找方法对象.这样数据库中的一张表会有一个查找方法类和一个入口来获得结果.
- 其和活动记录的细微区别在于后者含有领域逻辑.
- 使用时机
- 使用事务脚本时,通常使用行数据入口,来分离数据库访问代码,并且易于在不同的事务脚本中重用.
- 当其和事务脚本配合使用时.可能会发现业务逻辑在多处脚本中重复出现,
- 此时,将逻辑从脚本移动到入口时,入口就演变成了活动记录.这样减少了重复的业务逻辑.
- 充当数据源中单条记录入口的对象.每行一个实例.
- Active Record
- 封装了数据库访问的对象,包含数据库表或者视图中的某一行.并在这些数据之上增加了领域模型.
- 既有数据又有行为的对象.
- 把数据访问逻辑置于领域对象中.
- 运行机制
- 本质是领域模型.
- 该模型中的类和数据库中的记录结构匹配.
- 类的每个域对应表的每一个列.因此不需要映射.
- 每条活动记录负责向数据库保存和加载数据,并处理作用于数据之上的领域逻辑.
- 其和数据库间紧密耦合.所以常用静态查找方法.
- 使用时机
- 适用于不太复杂的领域模型(増删改查).
- 初始设计领域模型时,会在活动记录和数据映射器之间二选一.
- 活动记录.简单,易于创建.但是,仅当活动记录对象和数据库表直接对应,即同构时,比较有效.
- 其要求对象的设计和数据库的设计紧密耦合.不利于未来的重构.
- 在使用了事务脚本,并且开发时产生了很多的代码复制.那么
- 将表包装为入口,接着开始行为迁移,使表演化为活动记录.
- 封装了数据库访问的对象,包含数据库表或者视图中的某一行.并在这些数据之上增加了领域模型.
- Data Mapper
- 在保存对象和数据库(及映射器本身)彼此独立的前提下,在对象和数据库之间进行数据移动的层.
- 对于一个具有复杂业务逻辑的对象模型,其对象方案和关系方案是不匹配的.
- 运行机制
- 出于测试,或者使用单个领域层对应不同的数据库层时,可以替换整个映射器层.
- 由于对象间彼此紧密联系,所以必须在某刻停止读取,否则可能在一次查询中返回整个数据库.
- 此时,使用延迟加载.因此,内存中的对象不能完全忽略映射层.
- 使用时
- 常和领域模型一起使用.用以在数据库方案和对象模型需要独立演变时.
- 缺点是引入了新的层次.因此只有在业务逻辑复杂时才使用.