随笔分类 -  企业引用架构模式

Martin Fowler
摘要:架构架构的定义最高层次的系统分解.系统中不易改变的决定.主观上的,对系统的组成部分和各部分件交互关系的设计的可共享的理解.层次如何分层,以及层间如何协作.企业应用虽然部分模式适合于所有软件,但是大多数模式仅适合于某些特定领域和分支.特征持久化数据.程序多次运行都需要这些数据.数据的生命周期可能比软件都要长.数据可能会需要在不同的软件间迁移.数据本身的结构可能会被扩展,以在不影响既有信息情况下,表示更多的新信息.大数据.多人同时访问数据大量操作数据的UI.通常需要与散布在企业周围的其他企业应用集成.业务逻辑:很多的"一次性特殊情况"最终导致复杂的业务"无逻辑&quo 阅读全文
posted @ 2014-01-23 09:42 robynhan 阅读(158) 评论(0) 推荐(0) 编辑
摘要:Layer Supertype层超类型某一类型充当一层中所有类型的超类型.(DomainObject).运行机制当软件某一层中所有对象有公共特征时,可以将这些特征提取到一个超类上去.Separated Interface分离接口在一个包中定义接口,而在另一个与之分离的保重实现该接口.为了减少系统部件间的耦合,将类分组,然后组织成包,并限制包间的依赖关系.同时约定包间调用的约束.但是,可能会出现与包间通用的一般性依赖关系有冲突的调用关系.此时,使用分离接口.一个包中定义接口,而在另一个包中实现它.分离接口为入口提供了一个很好的插入点.运行机制实现类对接口存在依赖,反之没有.所以,实现包到接口包有 阅读全文
posted @ 2014-01-22 16:28 robynhan 阅读(260) 评论(0) 推荐(0) 编辑
摘要:在两个独立的对象之间建立通信的对象需要在两个必须相互隔离的子系统间建立通信.可能是因为无法修改已有的子系统,或者不愿意在两者之间建立依赖关系.甚至不愿意这两个子系统与另一个部件间建立依赖关系.运行机制控制着子系统键的通信细节.但是并不被子系统感知.难点是如何激活映射器进行(在子系统间的)数据交换.因为无法在任何一个子系统上直接调用Mapper.可以使用一个第三方子系统来完成映射并调用Mapper.也可以让Mapper成为某个子系统的观察者.使用时机作用是解耦系统的不同部分.完成该目的,也可选择入口.入口是最常见的方案.只有当需要确保任何一方的子系统都不能依赖于交换时,才使用它. 阅读全文
posted @ 2014-01-22 11:06 robynhan 阅读(770) 评论(0) 推荐(0) 编辑
摘要:Client Session State 客户会话状态.在Client端保存会话状态.运行机制Client在每次请求时会把所有的会话数据传给Server,Server在响应时把所有的会话状态传给Client.可以是完全无状态的Server.通常使用可序列化的DTO对象来传递数据.在HTML中,可选的是:URL参数,表单的隐藏域,Cookie.使用时机支持无状态的Server对象.从而提供了最大的集群性能和容错恢复.适合于小数据量.当数据量大时,保存和传输会有较大的延迟.安全问题.所有送到客户的数据都很容易泄露或被篡改.而加密又会影响性能.会话标识号一般使用Client会话状态.Server S 阅读全文
posted @ 2014-01-21 15:20 robynhan 阅读(470) 评论(0) 推荐(0) 编辑
摘要:用一个锁Lock一组相关的对象有时,需要按组来修改多个对象.这样,在需要锁住其中一个的时候,必须连带地将其他的对象都上锁.为每一个对象都加上一个锁是很繁琐的.粗粒度锁是覆盖多个对象的单个锁.简化了加锁行为.且不必为了给它们加锁而加载所有对象.运行机制为一组对象建立一个控制点.使用乐观离线锁让组中每个对象共享一个版本号来建立一个控制点.增加这个版本号时,就成为一个锁住组中所有对象的共享锁.需要在模型中指定该组的每个对象.共享的悲观离线锁要求组中每个对象共享某种锁标记.通过这个锁标记来锁住它们.一个共享的版本对象就是最好的锁标记.作为数据修改的基本单位的一组相关对象可看成一个aggregate聚集 阅读全文
posted @ 2014-01-21 14:23 robynhan 阅读(1427) 评论(0) 推荐(0) 编辑
摘要:每次只允许一个业务事务来访问数据,以防止并发业务事务中的冲突.离线并发处理通常会出现多个业务事务操作同一数据.最简单的办法是为整个业务事务保持一个系统事务.但是事务系统不适合于处理长事务.首选乐观离线锁.而悲观离线锁,作为它的补充.从一开始就避免冲突.它要求业务事务在对数据进行操作前就必须获取该数据的锁.一旦开始了一个业务事务,就确信不会再提交时由于并发冲突而被迫回滚数据.运行机制决定使用哪种锁exclusive write lock独占写锁.写目的的会话数据时使用,当对数据的读取要求不高时.exclusive read lock独占读锁.仅是为了读目的时的数据.限制了并发性.read/wri 阅读全文
posted @ 2014-01-21 12:28 robynhan 阅读(537) 评论(0) 推荐(0) 编辑
摘要:Remote Facade远程外观在OO模型中,存在很多规模小,且有小方法的对象.这些小对象会导致很多的对象间交互.在单一地址空间里,小对象没问题.但是,当在两个进程间做调用时,频繁的跨进程交互会造成性能开销.远程外观,减少远程调用的次数.建立在大量的细粒度对象之上,提供一个粗粒度的外观.不包括任何的领域逻辑.只是将方法转换到细粒度对象上.运行机制细粒度对象适合于解释复杂的逻辑.远程外观使用bluck accessor来使用一个getter/setter来完成在细粒度对象中的所有gettter/setter.单个远程外观,也可以作为多个细粒度对象的一个远程入口.远程外观的设计基于特定的客户需求 阅读全文
posted @ 2014-01-21 09:55 robynhan 阅读(574) 评论(0) 推荐(0) 编辑
摘要:MetaData Mapping元数据映射在MetaData中保存object-relation映射的详细信息.以表格形式定义映射,并可由通用代码来处理映射.运行机制MetaData中的信息如何以运行时Code的形式表现.Code Generation程序:输入是MetaData,输出是映射实现类的SourceCode.在编译前在构建流程中自动生成.应保证将它完全合并到构建流程中,且不应该手动编辑它.Reflective Program把方法/域视为数据.从MetaData文件中读入域和方法的名称,并用它们实现映射.性能慢,且会产生难以调试的代码.代码生成缺乏动态性,改变映射需要重新编译和部署 阅读全文
posted @ 2014-01-20 14:18 robynhan 阅读(705) 评论(0) 推荐(0) 编辑
摘要:使用将若干相似的类映射为单表,对拥有许多特殊数据的类使用具体表继承.对高层次使用类表继承,对低层次使用具体表继承.Single Table Inheritance在DB中将类继承层次设计为一个单表,表中各列代表不同类中的所有域.运行机制每个类负责把与之相关的数据保存在表的一行中.表中其它不相关的列留空.通过表中的Type字段来决定向内存中加载对象时,应该实例化那个类来创建该对象.可以直接使用类名称或者需要经过翻译的Code域.保存数据的代码可以由层超类负责.使用时机优点只需要关注一个DB表.获取数据时不必进行连接.对继承层次的重构(在父子之间挪动某个域)不需要修改DB.缺点DB表的列和对象的域 阅读全文
posted @ 2014-01-17 17:32 robynhan 阅读(366) 评论(0) 推荐(0) 编辑
摘要:Embedded Value把一个对象映射成另一个对象表中的若干字段.OO系统中会有很多小对象(DataRange,Money).而作为表在DB中毫无意义.默认想法是把一个对象保存为一个表.但是,将这些小对象,映射为该对象所有者记录中的若干字段.运行机制可以看做一种特殊的依赖映射.该值对象是一个依赖者对象.由所有者完成对依赖者的加载和保存.使用时机简单的值对象.由于没有ID.所以更新时不需要标识映射来同步.所以不需要DB表来对应.一般,只用在简单的依赖者上.只在一对一关联关系时,才使用.或者依赖者数量很少且固定时.如果想在SQL查询中使用依赖者值时,需要使用它.对于复杂的依赖关系(巨大的对象子 阅读全文
posted @ 2014-01-17 14:39 robynhan 阅读(439) 评论(0) 推荐(0) 编辑
摘要:让一个类为其子类(泛意上的)执行DB映射一些对象肯定会出现在另一对象的上下文中.此时,使用另一对象的Mapper来执行第一个对象的映射,来简化映射过程.运行机制在DB持久化时,依赖者类依赖于所有者类.每个依赖者只能有一个所有者.活动记录和行数据入口依赖者类的映射代码都写在所有者中.数据映射器没有依赖者的映射器类,在所有者的映射器中完成依赖者的映射代码.表数据入口根本没有依赖者类.在所有者中完成对依赖者的处理.通常,加载一个所有者时,会把相关的依赖者加载.当该相关加载耗费很大时,会使用延迟加载.依赖者没有标识域.也就不用存储到一个标识映射中.不能通过ID由查找方法加载.从而没有依赖者的查找器,而 阅读全文
posted @ 2014-01-17 12:24 robynhan 阅读(633) 评论(0) 推荐(0) 编辑
摘要:把关联保存为一个表,存储关联表的外键在对象中,使用集合作为域值,来处理多值域.而在DB中,只能有单值域.外键映射的核心,是在关联关系的单值端使用外键来维持联系.而在多对多的关联关系中,已经不存在单值端了.运行机制使用一个链接表来保存关联关系.仅有两个字段,即两个关联表的外键ID.对于每一对相关联的对象,它会有一个数据行与之对应.链接表没有对应的内存对象.所以也就没有ID.其主键是两个关联表的主键的组合.从链接表中加载Data需要两次查询,例如为雇员加载机能的问题1,查询EmployeesSkills表,得出该雇员关联的所有行.2,根据这些关联行的ID,查找出所有的机能对象.当内存中已存在这些信 阅读全文
posted @ 2014-01-17 11:00 robynhan 阅读(398) 评论(0) 推荐(0) 编辑
摘要:把对象间的关系映射到DB表键的外键引用对象之间可以通过对象引用来互相直接访问.运行机制关键是标识域.一对一的关联.使用一个DB的外键取代.一对多的对象集合.不能在DB中把相连的对象集合都保存了.必须颠倒引用的方向一张唱片有多个曲目,那么在曲目表中保存唱片的外键.更新时较为麻烦插入和删除在多的一方(曲目)是依赖映射时(只能被唱片所拥有,而不能被其它处引用).容易实现.删除与唱片相连的所有曲目,再把唱片中所有当前曲目记录插入进来.加入一个向后指针为了让关联双向化.在曲目上加入一个指向唱片的链接.改变了对象模型,可以以处理单值域的技术来处理更新.进行一次区分通过数据库的当前状态区分.从DB中重读(曲 阅读全文
posted @ 2014-01-17 10:20 robynhan 阅读(461) 评论(0) 推荐(0) 编辑
摘要:在对象中保存DB的ID字段,以维持内存对象和DB数据Row之间的identify.关系DB使用key来区分数据行.而内存对象不需要这样的键.因为对象系统能够保证身份确认.读取时没有问题,但是为了正确地写回DB.需要联系两者.本质上,只是将DB表的主键存储在对象的field上.工作机制键的选择meaningful key.应保证唯一性和恒定性.而这种检查是滞后的(Data已经进入DB后才可行).所以它是不可信的.meaningless key.由Db构造的,无用的随机数.简单/组合键Simple键.只使用一个DB字段.优点是完全一致性(所有的键操作都可以使用相同的代码).compound键.使用 阅读全文
posted @ 2014-01-16 11:28 robynhan 阅读(710) 评论(0) 推荐(0) 编辑
摘要:一个对象,它虽然不包含所需要的所有数据,但是它知道怎么获取这些数据设计专门的对象来把数据从DB中加载到内存中.该对象可以完成在加载所需对象的同时,把与之相关的对象也一并加载了.否则,必须显示加载所有所需的对象.但是,加载一个对象可能会引起大量相关对象的加载.当真正需要的对象只有几个时,会损害系统的性能.延迟加载会暂时中止该关联加载过程.以使需要的数据在用到时才被加载.运行机制延迟初始化 Lazy initialization思想.每次访问属性Field时,先检查是否为空..必须保证field是自封闭的.也就是所有对该field的访问(即使来自类内部),都要通过get方法实现.使用null来标记 阅读全文
posted @ 2014-01-15 17:17 robynhan 阅读(703) 评论(0) 推荐(0) 编辑
摘要:通过在Map中保存每个已加载过的对象,确保每个对象只加载一次.当要访问对象时,首先检查标识映射,看需要的对象是否已经存在其中.使用Identify来确保不重复加载相同的数据,不仅有助于保证正确性(不会将同一数据加载到两个不同的对象上),还能提升性能.运行机制基本思想:使用一系列映射.这些映射包含了从DB读出的对象.键选择当DB的键只有一列,且不可改变时,最自然的就是DB的主键.通常,一个以简单数据类型的代理主键,可以作为映射的键.显示还是通用.显式的.为每一种需要的对象提供不同的方法.findPerson(1).推荐.强类型有利于编译时检查.显示的接口.但是每增加一个映射就要加入一个方法.通用 阅读全文
posted @ 2014-01-15 14:40 robynhan 阅读(1043) 评论(0) 推荐(0) 编辑
摘要:维护受业务事务影响的对象列表,并协调变化的写入和并发问题的解决.从DB中存取Data时,必须记录增删改动作,以将对DB有影响的数据写会到DB中去.如果在每次修改对象模型时就对DB进行相应的修改,会造成大量小规模的DB调用,降低了速度.工作单元记录业务事务中对DB有影响的所有变化.然后在操作结束后,了解所有需要对DB做的改变.运行机制如何知道应该记录那些对象.可以由调用者实现,或者让发生变化的对象通知工作单元.caller registration用户改变了某个对象后,必须将它注册到工作单元.没有注册的对象在提交时都不会写入DB.允许在内存中改变对象而又不将它写入DB.但是,要达到这样的目的,最 阅读全文
posted @ 2014-01-15 11:16 robynhan 阅读(692) 评论(0) 推荐(0) 编辑
摘要:Table Data Gateway充当数据库表访问入口的对象.一个实例处理一个表中所有的行.在应用逻辑中混杂SQL语句会引起问题.表数据入口包含了用于访问单个表或者视图的所有SQL.其他代码调用它的方法来实现所有与数据库的交互.运行机制其用于数据读写,因此是无状态的.每个方法都将输入参数映射为SQL调用并在数据库连接上执行该语句.从查询返回信息返回简单数据结构,如Map.缺点是破坏了编译时检查.采用额外的数据传输对象.使用时机表数据入口同表模块可以很好地使用.它产生一个记录集数据结构,然后由表模块处理.它特别适合于事务脚本.一般不和领域模型一起使用.表数据入口能够很好滴运行在任何平台上,因为 阅读全文
posted @ 2014-01-14 17:08 robynhan 阅读(574) 评论(0) 推荐(0) 编辑
摘要:Transaction Script使用过程来组织业务逻辑,每个过程处理来自表现层的单个请求.运行机制尽可能将其放置于与表现层和数据源层隔离的类中.为了便于修改和测试,不能调用任何表现层逻辑.组织成类一个类,围绕一个主题将相关事务脚本组织在一起.Command模式.一个事务脚本对应一个类.优点:允许在运行时以对象的方式来操控脚本类的实例;便于解决线程相关问题.使用时机.胜在简单.当业务逻辑复杂时,很难保持良好的设计.会出现事务之间的冗余代码的问题.Domain Model合并了行为+数据的领域的对象模式.创建了一张由互联对象组成的网.运行机制创建一个完整的由对象组成的层,来对目标业务领域建模. 阅读全文
posted @ 2014-01-14 14:58 robynhan 阅读(607) 评论(0) 推荐(0) 编辑

点击右上角即可分享
微信分享提示