可以有多个数据存储层来实现对同一个对象的访问 - 例如,一个主要的“数据库”数据存储源来实现大多数对象,另一个“ldap”源来实现用户对象。在这种情况下,用户可以选择来自LDAP源,可能具有略微不同的功能(例如,无法保存/更新用户对象),但否则应用程序将以相同的方式使用它。另一种数据存储类型可能是Web服务或外部数据库。
我们正在考虑两种主要的实现方式,我和我的同事在基本层面上存在分歧,希望能够得到一些建议,哪种方法最好使用。我将尽力保持对每种方法的描述中立,因为我正在寻找一些客观的观点。
业务对象是基类,数据存储对象继承自业务对象。客户端代码处理数据存储对象。
在这种情况下,每个数据存储对象都继承了通用的业务规则,直接由客户端代码使用数据存储对象。这意味着客户端代码确定为给定对象使用哪种数据存储方法,因为它必须显式声明一个该类型的对象实例。客户端代码需要显式地知道每种使用的数据存储类型的连接信息。
如果数据存储层为给定对象实现了不同的功能,则客户端代码在编译时显式知道它,因为对象看起来不同。如果更改了数据存储方法,则必须更新客户端代码。
业务对象封装数据存储对象。
在这种情况下,业务对象直接由客户端应用程序使用。客户端应用程序将基本连接信息传递到业务层。关于给定对象使用哪种数据存储方法的决策由业务对象代码进行。连接信息将是从配置文件中获取的一块数据(客户端应用程序实际上并不知道/关心其详细信息),其中可能是一个数据库的单个连接字符串或多个不同数据存储类型的连接字符串的几个部分。还可以从另一个位置读取其他数据存储连接类型,例如指定各种 Web 服务的 URL 的配置表中。
这里的好处是,如果为现有对象添加了新的数据存储方法,则可以在运行时设置配置设置以确定使用哪种方法,并且对客户端应用程序完全透明。如果给定对象的数据存储方法发生更改,则不需要修改客户端应用程序。
业务对象是基类,数据源对象继承自业务对象。客户端代码主要处理基类。
这与第一种方法类似,但客户端代码声明基本业务对象类型的变量,并且业务对象上的 Load()/Create()/etc 静态方法返回相应的数据源类型的对象。
这种解决方案的架构类似于第一种方法,但主要区别在于关于为给定业务对象使用哪个数据存储对象的决策由业务层而不是客户端代码进行。
我知道已经存在提供某些功能的 ORM 库,但请暂时忽略它们(可能使用其中一个 ORM 库实现数据存储层)-还请注意,我故意没有告诉您正在使用的语言,除了它是强类型的。
我在寻求一些通用建议,关于哪种方法更好使用(或随意提出其他建议),以及为什么。