gpt4 book ai didi

c# - 如何为不同的数据源实现 Data Mapper/Repository 持久化模式?

转载 作者:太空狗 更新时间:2023-10-29 23:33:01 25 4
gpt4 key购买 nike

我正在从头开始编写一个新的网站项目。该项目是在 C# 中,但我的背景是在 PHP 中(下面的伪代码有点混合,试图既简洁又声明)。

问题

我需要从两个地方之一检索配置数据——有时从本地数据库,有时从 Soap 服务。我应该能够从任一来源创建相同的模型对象集。

数据以完全不同的结构存储在不同的数据源中 - 需要从 Soap 端将几个不同的 Soap 响应拼凑在一起,而 DB 结构更接近于我在代码中构建模型对象的方式.

配置由对象树组成:产品包含属性,其中包含选项条件> 当他们申请时。

目标

我想尽可能地分离关注点(希望促进测试/维护/扩展能力):

  • 我的模型对象应该对数据持久化或检索一无所知
  • Data Persistence 对象应该尽可能与数据源的确切类型无关
  • 我想尽可能将对象创建分开。

问题

我知道围绕此的各种设计模式(尽管我不完全确定我完全理解它们)。我 asked a question on Programmers与此类似并得到关于 Persistence Ignorance 的回复( more here ) 和 Repository模式,这两个似乎都是来自 Microsoft 世界的概念。

据我所知,“持久性无知”只是让模型对象对您的数据存储机制一无所知的概念,并且存储库模式看起来与数据映射器模式非常相似,除了它 may be more of a facade ,隐藏了更多实际发生的事情。

所以我的问题是:

在数据映射器模式中,每个模型对象应该有一个映射器吗?而不是为整个配置树设置一个?

因此,我是否应该有一个使用所有这些 Mapper 对象的配置树构建对象?

class ConfigBuilder() {
public ConfigBuilder (productMapper, propertyMapper, optionMapper, conditionMapper) {
// save them into local properties
}

public Products() {
var products = productMapper.FetchAll();

foreach (var product in products) {
AddProperties(product);
}

return products;
}

private AddProperties(products) { /* ... */ }
private AddOptions(property) { /* ... */ }
private AddConditions(option) { /* ... */ }
}

这看起来是个不错的解决方案吗?

构建对象的逻辑应该位于何处?

在某些时候,需要大量的逻辑来根据我从 Soap 服务返回的随机 XML 数据数组构建我的配置对象,并需要少量的逻辑来从数据库中执行相同的操作。

我是否应该将构建对象的逻辑放在 Mapper 对象的单独实例中?

interface IProductMapper { FetchAll; FetchByCode; Create; Delete; Update  }

class ProductMapperXml implements IProductMapper {
public ProductMapperXml(xmlDataSource) {}
public FetchAll() { /* A whole bunch of logic to create the Product objects from XML data source */ }
}

class ProductMapperDatabase implements IProductMapper {
public ProductMapperDatabase(databaseConnection) {}
public FetchAll() { /* Select and build products from the database */ }
}

这样可以吗?这个逻辑是否应该进一步抽象?如果是,为什么?此外,我对 ProductMapperXml 对象本身具有相当大的逻辑并且还负责在内部创建 Product 对象感到有些不安。我应该向它传递某种类型的 ProductFactory 吗?还是只使用工厂方法?

请让我知道是否有比我的建议更优雅的方法来解决这个问题?另外,如果我错过了任何抽象层或设计模式,我可以从中受益吗?

最佳答案

由于没有答案,我将自己写下来。

我最终选择了 DataMapper 模式 - 我希望我以一种明智的方式实现了它。

我最终没有使用任何工厂类,因为我能够通过类本身构建树。

我创建了一堆 Mapper 接口(interface):

interface Models.Interfaces.IModel {}
interface Mappers.Interfaces.IMapper {}
interface Mappers.Interfaces.IDatabaseMapper : IMapper {}
interface Mappers.Interfaces.IXmlMapper : IMapper {}

我为一切创建了模型:

class Models.Product : IModel {}
class Models.Property : IModel {}
class Models.Option : IModel {}
class Models.Condition : IModel {}

然后我给每个模型两个映射器类:

class Mappers.ProductDatabaseMapper : IDatabaseMapper {}
class Mappers.ProductXmlMapper : IXmlMapper {}
/* ... (same for each model) */

每个 Mapper 类都有创建其子类的方法:

class ProductDatabaseMapper :IDatabaseMapper {
public List<Product> FetchAllWithChildren {
var productRows = DbManager.FetchAll("Product");
var products = List<Product>();

foreach(var productRow in productRows) {
var product = new Product(productRow["Name"]);
product.Properties = PropertyManagerInstance.FetchAllWithChildren(product);
products.Add(product):
}

return products;
}
}

我认为这是一个相当巧妙的解决方案。尽管我仍然有点担心我的各种 Mapper 类正在自己创建对象这一事实。但我认为我只会在必要时将其分离到工厂中。

关于c# - 如何为不同的数据源实现 Data Mapper/Repository 持久化模式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12953660/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com