1.工作单元维护受业务事务影响的对象列表,并协调变化的写入和并发问题的解决。从数据库中存取数据时,记录所修改的内容是非常重要的;否则,那些改变的数据将不会被写回到数据库中。同样,必须插入创建的新对象和移除已删除的对象。可以在每次修改对象模型时对数据库进行相应的修改,但这样会产生大量规模很小的数据库调用,从而导致速度变慢。而且这样做还需要有一个对整个交互过程都开发的事务。如果存在一个贯穿多个请求的业务事务,这就是不合实际的。工作单元记录在业务事务过程中对数据库有影响的所有变化。操作结束后,作为一种结果,工作单元了解所有需要对数据库做的改变。1.运行机制引发你去处理数据库的明显原因是变化的:创建新对象和更新或删除已经存在的对象。工作单元就是一个记录这些变化的对象。只要开始做一些可能会对数据库有影响的操作,就创建一个工作单元去记录这些变化。每当创建,改变或者删除一个对象时,就通知次工作单元。也可以让此工作单元知道所读过的对象,通过验证在整个事务处理过程中数据库中的所有对象都没有改变,从而检查不一致性。工作单元的关键是在提交的时候,它决定要做什么。它打开一个事务,做所有的并发检查(使用悲观锁或者乐观锁)向数据库写入所在的修改。开发人员根本不用显式调用数据库更新方法。这样,他们就不用担心记录所修改的内容或者不必担心引用完整性如何影响他们的操作顺序。为了做到这一点,工作单元需要知道它应该记录哪些对象。可以由调用者实现,也可以让发生变化的对象通知工作单元。a) 用调用者注册的方式,用户如果改变了某个对象就必须将它注册到工作单元。任何没有注册的对象提交时都不会写入数据库。b) 用对象注册的方式,调用者就不再负责注册。这里常用的技巧是把注册方法置于对象方法中。从数据库加载对象会将加载的对象注册为'干净的';setting方法会将要设置的对象注册为'脏'的。为了使得这种方法可行,工作单元要么被传递给对象,要么被放在一个众所周知的地方。即使进行对象注册,也要需要注意一些地方,这就是,对象开发者必须记住在适当的地方加入注册调用代码。c) 另一种技术是工作单元控制器。在这里,工作单元控制所有数据库的读操作,一旦对象呗读取,就将它注册为'干净'的对象,而不是将对象标记为'脏'对象。工作单元在读操作的时候将产生一个拷贝,在提交时比较当前对象和拷贝对象,看对象是否发生了变化。虽然这加重了提交过程的负担,但是使得只对那些真正改变了的域进行有选择的更新;也避免了在对象域内执行注册调用。一个折中的方法是只拷贝改变了的对象。这需要注册,但是它支持有选择的更新,因此当读操作大大超过写操作时,它还会极大的降低拷贝操作的负担。工作单元的另一个用武之地是当数据库使用引用完整性时用它来保证更新顺序。大多数情况下,只需要保证数据库在事务提交时检查引用完整性即可,无需在每次sql调用时都检查。工作单元是确定更新次序最自然的地方。在小型系统中,可以用显式代码来实现这一点,该代码中包含了根据外键决定先写哪张表的系统。在较大应用中,最好用元数据指出按照什么样的顺序写数据库。可以用相似的技术最大限度的减少死锁的可能性。如果每个事务都按照相同的顺序处理需要进行编辑的白鸥,就会大大降低死锁的风险。工作单元是保存固定写表顺序的理想地方,这样总可以用相同的顺序来访问表。对象要能够找到它们当前的工作单元。对此,好的方法是用一张线程范围内的注册表。另一个方法在分发调用或者对象创建时,把工作单元传递给需要它的对象。每种方法都必须保证访问工作单元的线程不超过一个,否则会有意想不到的结果。工作单元也是处理批量更新的方法之一。批量更新的思想是把若干sql命令作为一个单独的单元发送,这样可以在一次单独的远程调用中得到处理。在快速连续发送很多个更新,插入和删除命令时这种思想很重要。工作单元不仅能作用于数据库,还可以作用于任何事务资源,所以也可以用它来调整消息队列和事务监控。2.使用时机工作单元解决的基本问题是记录操作过程的各种对象,以便知道为了使内存中的数据与数据库同步需要考虑哪些对象。最简单的办法是,在修改一个对象时就显式的保存该对象。但是带来的问题可能使用数据库的调用比想象的多。要避免多重数据库的调用,可以把对数据库的更新操作放到最后。为了做到这一点,需要记录已经改变的所有对象。可以在代码中用变量来实现记录跟踪,但是一旦变量很多,变量很快难以管理。一般来说,变量与事务脚本运行得很好,但很难与领域模型一起使用。把每个所改变的对象加上'脏'标记的做法要比把对象保存在变量中好。在事务处理完后,需要找出所有加了'脏'标记的对象并把它们写入数据库中。这项技术取决于寻找'脏'对象的难以程度。如果所有的'脏'对象都在一个单一层次结构上,就可以遍历该层次结构向数据库写入所有被改变了的对象。然后,跨越一个更一般的对象网络是比较困难的。2.标识映射通过在映射中保存每个已经加载的对象,确保每个对象只加载一次。当要访问对象的时候,通过映射来查钊它们。1.运行机制标识映射最基本的思想是使用一系列映射,这些映射包含了从数据库读出的对象。在简单情况下,使用同构方案时,就要为数据库中的每张表建立一个映射。当从数据库加载对象时,首先要检查映射。如果映射中存在与要加载对象相一致的对象,返回该对象。如果不存在,访问数据库,加载对象的同时把它们写入映射以备将来引用。还有大量的实现策略需要考虑。同意,由于标识映射与并发管理交互,还应该考虑使用乐观离线锁。1.键选择首先要考虑的问题就是映射的键。最自然的就是选择相应数据库表的主键。如果键只有一列且不可改变则这种方法比较有效。一个代理主键非常适合这个用途,因为它可以把它作为映射的键。这些键通常是一个简单的数据类型,所以比较行为能高效运行。2.显式的还是通用的必须确定把标识映射设计为显式还是通用的。显式的标识映射为每一种需要的对象提供不同的方法,例如,findPerson(1)。通用的映射为所有的接收对象提供统一的方法,而用一个参数指出所需的对象类型,例如,find("Person",1)。最明显的好处是可以用通用和可重用对象支持通用映射很容易就能构造一个可重复使用的注册表,它为各种各样的对象服务,而且增加新的映射时并不需要更新。然后,还是推荐显式的标识映射。首先,在一种强数据类型的语言中用显式数据映射能够做编译检查。但是,其优点远不止于此,它还拥有显式接口的其他全部优点:比较容易看到哪些映射是可用的,它们怎么被调用。虽然这意味着每增加一个映射就要加入一个方法,但对显式化的优点来说也不过是一个小的负担。3.数量标识映射的数量选择范围可以从一个类对应一个映射到整个会话对应的一个映射。只有当数据库有唯一键时才选用整个会话使用一个映射。一旦建立标识映射,其好处在于只有一个地方可以访问,也不会出现关于继承的严重错误。如果用多映射,最自然的方法是每个类或每个表对应对应一个映射,如果数据库方案和对象模型是相同的,这种方法很适用。如果二者不同,通常来说使映射基于对象比基于表容易一些,因为对象并不需要真正知道映射的复杂关系。4.把标识映射放到哪里标识映射必须放在容易找到的地方。也可以把它们捆绑到当前进程的上下文中。要确保每个会话都有自己的实例,并独立于任何其他会话的实例。因此,要把标识映射放到某个特定会话的对象中。如果正在使用工作单元,则把标识映射放到工作单元中。到目前为止,工作单元是防止标识映射最理想的地方,因为工作单元负责记录进出数据库的数据。如果没有使用工作单元,最好的位置是捆绑到会话的注册表。2.使用时机一般来说,用一个标识映射来管理所有修改了数据库读出对象。主要是不希望出现两个内存对象对应同一条数据库记录的情形---在这种情形下可能会因为2次对记录的修改不一致而使数据库映射混乱。标识映射的另一个用途是作为数据库表读取操作的高速缓存。也就是说,不需要每次访问某数据都去访问数据库。不变对象可能用不着标识映射。如果不会改变一个对象,那么也就不必担心修改异常。既然值对象是不变的,自然就不需要对值对象使用标识映射。尽管如此,标识映射仍然有其优点,最重要的优点就是高速缓存的性能高;另外一个优点是它有助于防止使用相等测试的错误形式,如Java中不能覆盖==,因此常常出现错误的相等测试。对依赖映射不需要建立标识映射。因为关联对象的存在受父对象的控制,没有必要用映射保存标识。3.延迟加载一个对象,它虽然不包含所需要的所有数据,但是知道怎么获取这些数据。为了把数据从数据库加载到内存中,设计专门的对象会使加载更加方便。这样在加载所需对象的同时也可以把与之相关的对象加载到内存中。这会使得开发人员进行加载更加容易,否则必须显式加载所有需要的对象。然后,如果由这个逻辑得出结论,就会出现这种情况:加载一个对象会引起大量相关对象的加载。当真正需要的对象只有几个的时候,这样做会损害系统的性能。延迟加载会暂时中止这个加载过程,方法是在对象结构中设立一个标志以便使需要的数据在用到时才被加载。1.运作机制主要有4种实现延迟加载的方法:延迟初始化,虚代理,值保持器和重影。a) 延迟初始化是最简单的方法。它的基本思想是每次访问属性域都要先检查该域是否为空。如果为空,在返回域值之前计算出这个域的值。为了实现这一点必须确保这个域是自封装的,也就是说所有对该域的访问,即使来自类的内部,都要通过获取方法来实现。用null来标记一个还没有加载的域也很有效,除了null是域中的合法取值的情况。在这种情况下,需要用其他的符号来标记还没有被加载的域,或者需要对空域使用特殊情况。使用延迟初始化很简单,但是它往往会在对象和数据库间加强依赖关系。正因为如此,它最适用于活动记录,表数据入口和行数据入口。如果用数据映射器,需要一个附加的间接层,这可以通过虚代理获得。b) 虚代理虚代理是这样一个对象,它看起来是应该在域中的一个对象,但实际上它并不包含任何东西。只有当它的一个方法被调用的时候,它才从数据库加载恰当的对象。虚代理的优点是它看上去完全就是需要放在那里的对象。但其缺点也就是在于它并不真的是那个对象,所以很容易就会陷入令人恼火的问题。另外,同一个实对象可以有很多虚代理。所有这些代理会有不同的对象特性,然后它们代表同一个概念上的对象。至少必须覆盖相等方法并记得用它而不是标识方法进行相等测试。如果没有它,将会遇到某些很难追踪的漏洞。在某些环境中会出现另外一个问题:必须创建大量的虚代理,甚至要为每个正在代理的类创建一个虚代理。在动态数据类型语言中经常可以避免这个问题,但在静态类型语言中,问题往往变得糟糕。c) 值保持器对领域类,可以通过使用值保持器避免这些问题。它是一个用来包装某个其他对象的对象。要想获取基对象,可以访问值保持器得到它的值,但是只有第一次访问值保持器时它真正从数据库读取数据。值保持器的缺点是类需要知道它的存在,而且将丧失强数据类型显式性。可以通过确保值保持器从未被传出它自己的类来避免标识问题。d) 重影重影(ghost)是部分状态下的真实对象。当从数据库加载对象的时候,它只包含其ID。当每次要访问某个域时,它就会加载器完全状态。把重影看成一个对象,它的每个域都是被一下子延迟初始化的,或者把它看成一个虚代理,对象本身就是它的虚代理。当然,在一次访问中,并不需要加载全部数据;可以把经常一起使用的分为一组,从而把数据分成不同的组。如果使用重影,可以直接把它放到它的标识中。这种方式可以维护标识和避免所有在读数据时出现的循环引用带来的问题。虚代理或重影不必完全没有数据。如果它们包含某些需要快速获取或经常用到的数据,在加载代理或重影时加载这些数据是很有意义的(有时称为轻对象)。继承常常会给延迟加载带来问题。如果要用重影,需要知道要创建什么类型的重影,如果没有正确加载数据,往往就很难说了。虚代理在静态数据类型中也会遇到问题。延迟加载的另一个风险是它容易导致产生超出需要的数据库访问。这种波动加载是一个很好的例子。2.使用时机什么时候使用延迟加载完全取决于加载一个对象时需要从数据库读取多少数据和数据库调用的次数。通常没必要对和对象的剩余部分处于同一行中的域使用延迟加载,因为大多数情况下在一次调用中读取剩下的数据不会有更多开销,即使数据域很大。从性能角度来说,取决于什么时候想取回数据。通常比较好的方法是在一次调用过程中取回所有需要的数据,这样可以随取随用,尤其是在这些数据对应于同一用户界面一次交互时。使用延迟加载的最佳时机是,需要额外的调用,并且当使用助对象时所调用的数据没有用到的时候。

https://juejin.im/post/5c55d393518825626b76c784

11.企业应用架构模式 --- 对象-关系行为模式相关推荐

  1. 查询oracle模式对象信息,ORACLE 模式和模式对象

    模式和模式对象一个模式(schema)为模式对象(scehma object)的一个集合,每一个数据库用户对应一个模式.模式对象为直接引用数据库数据的逻辑结构,模式对象包含如表.视图.索引.聚集.序列 ...

  2. 2.设计模式中状态模式(对象的行为模式)(Python实现)

    1.什么是状态模式? 2.状态模式的设计思想 3.状态模式的代码框架模型 4.分别用框架模型和不用框架模型来处理下面的例子 5.模型说明 6. 应用场景 1.什么是状态模式? 如水一般,状态即事物所处 ...

  3. 第十一天-《企业应用架构模式》-对象-关系行为模式

    1. 工作单元 用于维护受业务事务影响的对象列表,并协调变化的写入和并发问题的解决.如下: 1)运行机制: 关键: 是提交时,决定要做什么.它打开一个事务,做所有的并发检查(使用悲观离线锁或乐观离线锁 ...

  4. 第十三天-企业应用架构模式-对象-关系元数据映射模式

    元数据映射 (Metadata Mapping) 查询对象 (Query Object) 资源库 (Repository)

  5. Bridge模式——对象结构型模式

    今天看了Bridge模式,对其进行简单的总结,并给出几篇通俗易懂的文章链接. (一)意图--将抽象部分和它的实现部分分离,使它们都可以独立地变化. 适用于从多维度描述的类型,拆解开来,使其能沿着各维度 ...

  6. Proxy 代理模式 对象结构型模式

    1.意图 为其它对象提供一种代理以控制对这个对象的访问. 2.别名 Surrogate 3.动机 对一个对象进行访问控制的一个原因是为了只有在我们确实需要这个对象时才对它进行创建和初始化.我们考虑一个 ...

  7. 企业应用架构模式笔记

    1 企业应用模式概述 1.1 企业应用的模式 企业应用领域要解决的问题在某些方面要比做一个工具软件.或者一个电信通信软件等复杂的得多,比如纷杂的企业数据,各具特色的业务规则,变化莫测的用户需求.因此企 ...

  8. [201004][企业应用架构模式][王怀民][周斌][译]

    [201004][企业应用架构模式][王怀民][周斌][译] 模式列表 引言 0.1 架构 0.2 企业应用 0.3 企业应用的种类 0.4 关于性能的考虑 0.5 模式 0.5.1 模式的结构 0. ...

  9. 企业应用架构模式学习笔记

    1.概述 2.分层 表现逻辑处理用户与软件间的交互.表现层的主要职责是向用户显示信息并把从用户那里获取的信息解释成领域层或数据源层上的各种动作. 数据源逻辑主要关注与其他系统的交互,这些系统将代表应用 ...

  10. DM数据库管理模式对象空间、表、索引、触发器、视图、序列列、同义词等。

    一.管理模式对象的空间 模式对象的空间管理关系到空间的有效使用和数据的合理分布. 1.设置存储参数 对于普通表和索引,DM8提供了以下的存储参数: 初始簇数目INITIAL:指建立表时分配的簇个数,必 ...

最新文章

  1. AI 一分钟 | 独角兽旷视被爆明年一季度上市;阿里达摩院再得顶级大牛,计算机理论最高奖得主马里奥加盟量子实验室
  2. 下午花一小时整理的JVM运行时方法区
  3. UVA-10212 The Last Non-zero Digit. 分解质因子+容斥定理
  4. Mybatis获得参数值的两种方式:#{}和${}的区别
  5. 13篇顶会!25岁成985高校博导,入职半年发ICML,网友:万点暴击
  6. CentOS7安装Python3.4 ,让Python2和3共存
  7. commonjs 和 es6模块化开发入门
  8. 吴恩达深度学习5.2练习_Sequence Models_Operations on word vectors
  9. mysql rs.next_JDBC结果集rs.next()注意事项
  10. 使用XmlPullParser解析XML
  11. 数组、字典转json串,不支持字符串
  12. 使用NFC读卡器ACR122u读取银行卡信息
  13. proteus单片机仿真入门攻略(含元器件名称及它的图形)
  14. 《平潭史话》之平潭轮渡
  15. 按要求写mysql语句_根据要求写SQL 语句
  16. MAC电脑 系统 恢复出厂设置
  17. “快速原型法”在项目开发中的成功案例
  18. 怎么提高代码质量?-来自Google的研发经验总结
  19. HP DL380 G7 安装 6.5 紫屏
  20. 工信部区块链论坛 | 乐视金融CEO王永利:区块链技术研发和应用的实践经验

热门文章

  1. 强连通分量(Tarjan)模板
  2. ES6中的const命令【转】
  3. CoreData数据库版本迁移
  4. jQuery Callback 方法
  5. 利用dropbox来Host你的silverlight应用
  6. 趁老王不在,和隔壁邻居斗斗地主,比比大小
  7. 内推| 阿里全球化分析师战队集结令
  8. jenkins配置自动发送邮件
  9. [剑指offer] 7. 斐波那契数列 (递归 时间复杂度)
  10. [UVa11995] I Can Guess the Data Structure!