筑建网站首页,wordpress开头,律师在哪个网站做,jsp两种网站开发模式从简单到复杂依次为#xff1a;3.1.1 用户提供唯一标识这时用户将输入一些可识别的数值或符号#xff0c;或从已有标识中选其一#xff0c;然后创建实体对象。这是一种非常简单方案#xff0c;但也可能变得复杂。由于需用户自己生成高质量的标识。所以标识可能唯一#xf…从简单到复杂依次为3.1.1 用户提供唯一标识这时用户将输入一些可识别的数值或符号或从已有标识中选其一然后创建实体对象。这是一种非常简单方案但也可能变得复杂。由于需用户自己生成高质量的标识。所以标识可能唯一却有可能是不正确的。缺陷多数情况下标识不可变用户无法修改标识。但有时赋予用户修改标识值的权限有好处。例如若将Forum和Discussion的名字作为唯一标识那么发生拼写错误时怎么办或用户之后想采用新名字怎么办Forum名字拼写错误Discussion名字长度小于所要求的要改变这些标识值需要多大代价虽然用户提供的身份标识看似一种节约成本的做法但也有可能不是。此时我们还可以依赖用户来提供唯一的、正确、稳定的对象标识吗为避免上述问题需重新设计。开发需采用无故障的方法来保证用户输入的确是唯一的身份标识。虽然基于工作流的标识审批过程对于高吞吐量的领域并无多大帮助但是它对于生成具有可读性的身份标识来说却是必需的。如果这种方式生成的标识会在将来继续使用而工作流也是可能的那么添加一个额外的阶段来保证身份标识的质量是值得的。通常将一些用户输入作为实体属性这些属性可用于对象匹配但并不将这样属性作为唯一身份标识。简单属性可作为实体状态的一部分 他们更容易修改在这种情况下我们需要考虑另外的方法来生成实体的唯一标识。3.1.2 应用程序生成唯一标识很多可靠方法可自动生成唯一标识但若应用程序处于集群环境或分布在不同计算节点就要注意了有些方法可以生成完全唯一的标识比如UUID或者GUID。以下是生成唯一标识的另一种方法其中每一步生成的结果都将添加到最终的文本标识中计算节点的当前时间以毫秒记计算节点的IP地址虚拟机(Java)中工厂对象实例的对象标识虚拟机(Java)中由同一个随机数生成器生成的随机数以上可产生一个128位唯一值可通过一个32字节或36字节的16进制数的字符串表示。在使用36字节时可用连字符-来连接以上各步骤生成结果比如f36ab21c- 67dc-5274-c642-lde2f4d5e72ao在不用连字符时即为32字节。但这都是一个很大的唯一标识且不具可读性。在Java里以上方法被标准的UUID生成器所替代(自从Java 1.5)对应java.util.UUlD类。该类支持4种不同的唯一标识生成算法这些算法都基于Leach-Saiz变量。使用JavaSE API可简单生成伪随机的唯一标识 String rawld java.util.UUID.randomUUID().toString();以上代码使用了第4类算法该算法采用高度加密的伪随机数生成器而该生 成器又基于java.security.SecureRandom生成器。第3类算法采用对名字加密的方 法它使用了java.security.MessageDigest类。我们可以通过以下方式生成一个基于名字的UUIDString rawld java.util.UUID.nameUUIDFromBytes( Some text*.getBytes()).toString ();还可加密所生成的伪随机数SecureRandom randomGenerator new SecureRandom();int randomNumber randomGenerator.nextInt();String randomDigits new Integer(randomNumber).toString();MessageDigest encryptor MessageDigest.getlnstance(nSHA-l); byte[] rawIdBytes encryptor.digest(randomDigits.getBytes());接下来将 rawIdBytes 数组转换成16进制数的字符串表示即可。可先将随机数转换成字符串类型再将该字符串传给UUID的nameUUlDFromBytes。工厂方法。UUID是一种快速生成唯一标识的方法它不需要与外界交互比如持久化机制。即便需要在1秒钟之内多次创建实体UUID生成器也可应付。对有性 能要求的领域来说可缓存UUID实例使其在背后不间断地向缓存中填入新UUID值。如果缓存中的UUID实例由于服务器重启而丢失在不同唯一标识间不会存在缺口因为所有标识都是随机因此重新向缓存中填UUID值并不会对系统造成影响。对于如此大的唯一标识从内存使用角度看可能不实际。可采用由持久化机制生成的8字节长标识或甚至4字节长标识就够了。通常并不会在用户界面上显示UUID f36ab21c-67dc-5274-c642-lde2f4d5e72a若UUID可隐藏或可使用可读性的引用技术那便可使用完整UUID。比如可通过E-mail或其他消息机制发送具有URI的超媒体资源。此时超媒体链接中的文本部分便可以用于隐藏UUID,就像 HTML中text里的text。根据UUID能够表达实体的唯一程度可只使用UUID的一部分标记实体。在聚合(10)边界内可将缩短后的标识作为实体的本地标识。本地标识表示在同一聚合中一个实体的标识只需和该聚合中的其他实体区分即可。Aggregate(聚合)是一组相关对象的集合作为一个整体被外界访问聚合根(Aggregate Root)是这个聚合的根节点。聚合根(Aggregate Root)的实体则需要全局的唯一标识对于自己创建的标识生成器依然可用UUID的某部分。 比如对于APM-P-08-14-2012-F36AB21C该25字节的标识表示在敏捷项目管理上下文(APM)中创建的一个Product创建时间为2012年8月14日。额外的F36AB21C唯一标识即为UUID的第一部分该部分用于区分同一天所创建的不同Product。这样的标识满足可读性要求又提供很好的全局唯一性用户并非唯一受益者当这样的标识从一个限界上下文传到另一个时开发者可立即识别实体源头。对于SaaSOvation来说还可以向标识中加入租户信息。将这样的标识作为String来维护并不是一个好办法此时使用一个值对象更加合适String rawId APM-P-0 8-14-2012-F36AB21C ;// 即将生成 Productld productld new Productld(rawld);Date productCreationDate productld.creationDate();客户可询问标识的细节信息比如一个Product的创建时间就已包含于标识。客户无需知道原始的标识格式此时聚合根Product可通过creationDate方法向外界暴露该Produc啲创建时间而客户并不 需要知道对创建时间的获取细节。public class Product extends Entity {private ProductId productld;...public Date creationDate() {return this.productld().creationDate();}...}也可通过第三方类库框架来生产实体的唯一标识。比如Apache Commons的Commons Id组件,该组件提供了5种标识生成器。有些持久化存储比如Redis也可生成唯一标识。对于程序生成的标识来说,什么样的对象可以作为创建标识的工厂对象呢 对于聚合根的唯一标识我们可以采用资源库来生成唯一标识public class HibernateProductRepository implements ProductRepository (public Productld nextidentity() {return new Productld(java.util.UUID.randomUUID().toString().toUpperCase());}}将唯一标识的生成放在资源库中是一种自然的选择。持久化机制生成唯一标识若从DB获取一个序列值(Sequence)或递增值结果总是唯一。根据标识所需范围数据库可生成2字节、4字节和8字节的唯一标识。在Java中的这些大小整数分别可表示32,7672,147,483,6479,223,372,036,854,775,807种不同标识值。缺陷性能。从DB获取标识比APP生成慢得多。一种解决方法是将数据库序列缓存在APP比如缓存在资源库。这固然是一种好方法但若服务器节点需重启那么将失去很大一部分标识值区间。若丢失区间无法接受或只需相对较小标识值(2字节整数)这缓存机制便不实用也没必要。当然可以找回丢掉的标识值区间但可能引入新麻烦。如果可使用延迟生成那缓存标识便不是问题。以下是如何使用Hibernate和Oracle的序列来生成标识product_seq在采用MySQL的自增列时配置如下这种方式的性能是很好的同时配置Hibernate映射也是简单的。3.1.3 另一个限界上下文提供唯一标识若另一个限界上下文用于给实体标识赋值那需要对每个标识进行查找、匹配和赋值。最重要的是精确匹配。此时用户需提供一或多种属性比如账户、用户名和E-mail地址以精确定位需要匹配的结果。通常匹配的输入是模糊的导致多个查询结果此时用户需要手动选择如图从外部系统中获取需要查找的唯一标识。用户界面中可显示唯一标识(本图)也可不显示用户输入了模糊查找信息通过调用外部限界上下文的API返回的结果可能是0、1或多个匹配对象。接着用户要在结果中选择某特定对象。所选对象的身份标识将作为本地标识。外部实体的一些额外属性也可能被复制到本地实体。缺陷对象同步可能是个问题。外部对象的改变将如何影响本地对象如何知道所关联的对象已经改变了呢可通过事件驱动架构和领域事件解决。本地限界上下文订阅外部系统中的领域事件当本地上下文接收到外部系统的事件通知时它将相应更新本地对象。有时同步事件可能由本地上下文发出外部系统在接受到该事件时同样会做相应的更新操作。要达到这样的目的并不容易但这样做能够创建出更加具有自治性的系统。可将对象查找限定在本地对象中。这并不是说将外部对 象缓存在本地系统中而是将外部概念翻译成本地限界上下文中的概念。这是最为复杂的标识创建策略。要维护本地实体我们不但需要考虑由本地 领域行为所导致的改变还需要将外部系统也考虑在内。所以在使用这种策略时应持保守态度。参考《实现领域驱动设计》