如何创建一个灵活的架构,使我能够在多个不同的底层数据模型上运行?

How do I create a flexible architecture that allows me to operate on several different underlying data models?

我正在尝试创建一个具有非常灵活架构的应用程序。它应该能够轻松地用不同的组件替换任何一层,只要它遵循相同的接口。

更具体地说,我的业务逻辑层不应该关心我的数据层如何或在何处检索业务逻辑层请求的数据对象。或者数据层可能必须进行什么样的计算才能将数据对象转换为业务层可用的对象。

在我最初尝试解决这个问题时,我遇到的问题是当业务逻辑使用泛型时,数据层不知道如何处理这些类型。例如,假设我的业务逻辑在 Car 类型上运行。

abstract class Car
{
    public abstract int Wheels { get; set; }
}

虽然我的数据层可能在不同类型上运行,例如:

class VolvoCar : Car
{
    public override int Wheels { get; set; }
}

class HondaCar : Car
{
    public override int Wheels { get; set; }
}

取决于我当前使用的存储库,VolvoRepository 或 HondaRepository。这些是通过 IoC 容器注入的,因此业务逻辑不知道下面是哪个实现。这些 类 可能还有其他不同的属性,但我的业务逻辑层只关心 Car 的通用定义,而不必担心它是哪种汽车。

我的问题是:当我现在想使用泛型访问数据层时,层之间在它们操作的类型上存在脱节。例如,我的业务逻辑可能会向我的存储库请求 Get()。但是如果我的 Repository 是 VolvoRepository 类型,我真正想要它做的是实例化一个 VolvoCar 并且 return 它作为一个 Car。但我认为我的存储库没有任何简单的推断方法。当然可以通过丑陋的方式,比如反射或

if (T is Car) return new VolvoCar();

但我正在寻找一种更简洁的方法,即 "just works"。

简而言之,我怎样才能让我的业务逻辑可以简单地对类型的通用定义进行操作,而让数据层处理底层数据模型的特定问题? (例如,本田可能以两个一组的方式存储他们的车轮,因此加载 HondaCar 意味着在将车轮 属性 传递给业务层之前乘以 2,等等)

虽然这主要是一个体系结构问题,但我们将不胜感激以 C# 给出的示例。如果我的想法偏离了方向,我也愿意接受截然不同的方法。唯一的硬性要求是我需要我的业务逻辑能够在几个不同的数据模型之上工作,这些模型都包含大致相同的对象 (POCO) 的定义。然后数据层组件必须负责处理这些 POCO 和底层数据模型之间的转换。

好的,你的问题看起来比较清楚了。只要您喜欢 C# 示例:

public abstract class TypeUnsafeObject 
{ 
    public abstract object GetObject();
    public abstract void SetObject(object obj);
}

然后:

    public abstract TypeSafeObject<T> : TypeUnsafeObject
    { 
        public abstract T GetTypeSafeObject();
        public abstract void SetTypeSafeObject(T obj);
        public override object GetObject() {
            return GetTypeSafeObject();
        }
        public override void SetObject(object obj) {
            var typeSafeObj = obj as T;
            if (typeSafeObj != null) {
                SetTypeSafeObj(typeSafeObj);
            }
            else {
            // report failure
            }
        }
    }

现在,有些消费者只处理对象(只要对他们来说没问题)。请注意:您的 type-unsafe 层可以绑定到任何不同的 class 而不仅仅是 object。为了简单起见,我只是尽量让事情显而易见。

这是最简单的解决方案。

TypeUnsafeRepo repo = RepoFactory.GetRepoFor<VolvoCar>();
repo.Save();

同时 RepoFactory 响应强类型对象


但老实说,我看不出您为什么需要泛型来管理您描述的复杂性。我建议让事情变得非常非常简单,但 easy-to-understand.