专栏首页哲学驱动设计使用Repository模式支持产品的客户化

使用Repository模式支持产品的客户化

    本篇博客简单描述了Repository模式在OEA中的应用。

不使用Repository时的问题

    OEA框架中使用了DDD的思想,面向领域对象进行开发。在DDD中,有很多重要的概念,例如:聚合实体对象、值对象、仓储、工厂、服务等。(不太了解的Repository和DDD的朋友,可以看Evans写的《Domain Driven Design》。)

    在OEA中,实体的实现框架使用了CSLA分布式框架。原来为了简单并保持和CSLA开发模式的兼容,一直都把实体的获取模式直接以静态方法的方式直接写在实体的对应列表类中。例如下面这段代码:

    随着应用的慢慢深入,出现了一些问题:

  1. 不易支持客户化。OEA是基于产品线的开发,如果采用前面的开发模式,当客户化版本扩展了主干版本中的实体类时,由于主干版本中的代码直接使用静态方法,所以无法获取到扩展后的新类型的对象。(要了解OEA中客户化的具体方案,见《基于OEA框架的客户化设计(一) 总体设计》)
  2. 为了使用CSLA而写的这些获取代码,在以后引入非CSLA实体时,可能都需要重写。
  3. DDD的思想在代码中无法直接体现,使得对系统的理解和学习容易产生二意。
  4. 由于使用了静态方法,所以一些通用的代码的重用变得比较过程化,不易读。

    基于以上的原因,团队决定使用Repository模式进行代码的重构。

Repository如何解决以上问题

  1. 如何支持客户化 当客户版本以继承的方式使用子类B扩展了主干版本的实体类A后,主干版本中原有的代码虽然是面向父类型A的,但是此时其操作的对象应该动态地变为扩展后的子类B。使用Repository模式,我们在主干版本中通过Repository工厂找到需要的类型A的Repository,然后通过它获取具体的对象集合并进行操作。当扩展后,主干版本中同样的代码再次通过RepsotoryFactory获取A的Repository时,得到的其实是子类B的Repository,这样,它获取出来的对象集合都是B的列表。这样,就实现完全的类型扩展,而且主干中的代码不需要任何的改变。 而一旦实体类被动态扩展,相应的数据层和界面也就被OEA框架自动地进行了调整。
  2. 由于Repository其实是承担了原来的静态方法的职责,也就是实体对象的CDUQ,这些方法现在都变为元状态的Repository的实例方法。这样,通过继承的方式就能很好的实现代码的重用。同时,我们可以在Repository中管理一些整个实体类型的信息,例如某个实体类A的所有属性列表元数据。
  3. 由于Repository模式比较通用,其它实体框架都能比较容易地实现它,所以这样也为OEA以后替换为其它实体框架提供了可能。

    具体的看一下类图:

    可以看出,整个结构比较简单:

  1. RepositoryFactory通过EntityConvention来检测命名约定,并构建需要的EntityRepository。
  2. 元状态的EntityRepository对Entity和EntityList进行管理(CDUQ)。
  3. 实体类不依赖Repository,而是依赖ILazyProvider接口来实现引用对象或子对象的懒加载。通过ILazyProviderFactory来找到想要的懒加载提供器。
  4. EntityRepository提供ILazyProvider的实现,RepositoryFactory 提供 ILazyProviderFactory的实现。
  5. 具体的RepositoryFactory 被依赖注入到 Entity 层中,并被DIHost保存起来。

小结

    在OEA中使用Repository模式重构后,到目前为止已经使用了一个月左右,大家反应比起原来的调用模式好多了,同时还支持了客户化及其它实体框架引入的可能。总体上来说,重构还是比较成功的。

    在以前其它的系统的开发中,基本上也都使用到了Repository模式,这种模式在数据库应用程序的开发中,确实十分常用。以后可以考虑对它进行一些通用框架层面的设计。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • OEA 2.11 支持单机版数据库 - SQLite与SQLCE对比

    在 OEA 平台 设计中,需要支持多种数据库,这至少包括了 SqlServer、Oracle、一个单机文件数据库。而之前对于这一块,我们一直没有实现,只是预留了...

    用户1172223
  • 090615 T 数据库范式

    帮助记忆五级范式:     一级范式:         消除每个表格中重复的组。         为每套相关的数据建立一个独立的表格。         使用一个...

    用户1172223
  • OEA 中的多国语言实现

        本篇博客主要描述在 OEA 框架中的多国语言框架的原理及应用。 多国语言常见实现及原理分析     管理软件平台,一般来说,都应该支持多国语言,以支持应...

    用户1172223
  • 2020-5-8-repository模式

    今天和大家介绍一下一种特殊的设计模式——仓库模式(repository pattern)

    黄腾霄
  • Laravel使用repository模式

    当controller不使用Repository模式 ,在controller的各个方法中存在花式的数据库操作(这是非常糟糕的),如果需求变更,重写将变得非常困...

    gaobinzhan
  • Java并发:了解无锁CAS就从源码分析

    CAS的全称为Compare And Swap,直译就是比较交换。是一条CPU的原子指令,其作用是让CPU先进行比较两个值是否相等,然后原子地更新某个位置的值,...

    搜云库技术团队
  • JDK1.9-函数式编程

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

    cwl_java
  • Node.js CLI 工具最佳实践

    一个糟糕的 CLI 工具会让用户觉得难用,而构建一个成功的 CLI 需要密切关注很多细节,同时需要站在用户的角度,创造良好的用户体验。要做到这些特别不容易。

    ConardLi
  • C# 8.0 文件长度 Bytes 字节转 KB 等单位字符串

    本文将使用 C# 8.0 写一个相对比较省内存和性能不差的将文件长度从 Bytes 转换为单位使用 KB 或 MB 或 GB 等单位的字符串的方法

    林德熙
  • 字符集及其存储方式(解决乱码问题)

    阅读大概需要4分钟 在我们进行文本挖掘或处理文档时,都要面临一个最最基本的问题->就是解决乱码问题。在此,介绍最本质的字符编码。 我们熟悉的有三种:ASCII字...

    zenRRan

扫码关注云+社区

领取腾讯云代金券