【问题标题】:Elegant Solution for Initializing One Class (but not another)初始化一个类(但不是另一个)的优雅解决方案
【发布时间】:2012-03-31 00:24:22
【问题描述】:

我有一个应用程序支持两个数据访问层:db4o 和 RavenDB。逻辑类通过这样的调用来获取具体的数据类:

return DataAccessFactory.GetDataInterface<IApplicationData>().GetAll();

这是 DataAccessFactory 中返回正确 ApplicationData(db4o 或 RavenDB)具体类的方法:

public static T GetDataInterface<T>() where T : class
{
    T theObject = // Code here to get the object. Not relevant to this question.

    // Begin HACK

    DataAccessLayerBase theObjectAsRavenDalBase = theObject as DataAccessLayerBase;

    if (theObjectAsRavenDalBase != null)
    {
        theObjectAsRavenDalBase.SetAsInitialDalInstanceAndCreateSession();
    }

    // End HACK

    return theObject as T;
}

我实施的 hack 是转换为 RavenDB 的 DataAccessLayerBase 版本和 if 语句。如果具体类恰好是 RavenDB 类,那么我需要调用它的方法。 (此处显示的 DataAccessLayerBase 位于 RavenDb 命名空间中。db4o 也是他自己的 DataAccessLayerBase。)

解决此问题的一种方法是让每个 DataAccessLayerBase 实现一个通用方法,例如 Initialize()。 db4o Initialize() 方法什么都不做,而 RavenDB Initialize() 方法将执行必要的逻辑。然后这个方法可以简单地调用 Initialize() 而不关心它是哪个具体的类。

还有比这更好的设计吗?我认为我刚才描述的修复已经足够好,但我不禁认为我遗漏了一些东西。我正在寻找一种更好、更优雅的方法来解决这个问题。我提出的方法的一个缺点是其他数据访问层必须随后实现 Initialize(),即使我只需要 RavenDB。

注意:我不能只让具体类在创建时进行初始化,因为它应该只在调用 DataAccessFactory.GetDataInterface() 时发生。

【问题讨论】:

    标签: c# oop design-patterns


    【解决方案1】:

    另一种解决方案是在由 DataAccess 类实现的接口上添加类型属性。然后,您可以检查类型以了解是否需要调用 SetAsInitialDalInstanceAndCreateSession 方法。我认为您上面描述的 Initialize 方法也是一个很好的解决方案

    【讨论】:

    • 谢谢,TGH。您的选项听起来很像当前的实现:检查类型,并可选择调用方法。我希望有一个没有 if 检查的更多态的解决方案。
    • 是的,有很多相似之处。尽管可以避免强制转换...我认为您调用 Initialize() 的想法实际上是基于多态性的最佳方法。抱歉,我现在不能更有创意,但似乎试图以像这样的相同方法处理具有不同需求的对象将需要您在问题中描述的两种解决方案的一些变化。如果你有更多的类型,至少 Initialize() 的想法会很有意义......所以即使你只有两种类型,它仍然是合适的:-)......
    • 我也开始这么想了。有一种设计模式称为空设计模式。基本上,那些不需要做任何事情的数据类,就不会做任何事情。这样一来,他们都可以以同样的方式对待。并且由于该方法是应该调用该逻辑的地方,所以这是调用它的正确地方。感谢您帮助我解决这个问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-31
    • 2023-02-09
    • 1970-01-01
    • 2020-10-19
    相关资源
    最近更新 更多