访问数据层中的多个数据提供者

时间:2008-10-28 14:26:38

标签: nhibernate oop domain-driven-design dao data-layers

我正在开发一个使用DDD理念开发的业务应用程序。数据库通过NHibernate访问,数据层使用DAO模式实现。

UML类图如下所示。

UML Class Diagram http://img266.imageshack.us/my.php?image=classdiagramhk0.png http://img266.imageshack.us/my.php?image=classdiagramhk0.png

我不知道设计是好还是不好。你觉得怎么样?

但问题不在于设计是好还是坏。问题是在启动应用程序之后,在表示层中实例化IDaoFactory并将其作为参数发送到演示者类(使用MVC模式设计),如下所示

...
IDaoFactory daoFactory = new NHibernateDaoFactory(); //instantiation in main class
...
SamplePresenterClass s = new SamplePresenterClass(daoFactory);
...

只使用一个数据提供程序(只是一个数据库)很简单。但是现在我们也应该从XML获取数据。在开发的下一个阶段,我们应该连接到不同的Web服务并操纵传入和传出的数据。

将使用枚举键来获取XML中的数据。我们将一个名为XMLLoader的类添加到数据层,并将一个接口ILoader添加到域中。 XMLLoader有一个签名为

的方法
List<string> LoadData(LoaderEnum key)

如果我们在表示层中使用XMLLoader实例化ILoader,我们必须将它发送到将从数据层获取一些XML数据的对象。

ILoader loader = new XMLLoader();
SamplePresenterClass s = new SamplePresenterClass(daoFactory, xmlLoader);

实施Web服务访问类之后

SamplePresenterClass s = new SamplePresenterClass(daoFactory, xmlLoader, sampleWebServiceConnector1, sampleWebServiceConnector2, ...);

参数将及时增长。我想我可以在类中保存数据访问对象的所有实例并将其传递给所需的演示者(也许单例模式也可以帮助)。在域层中必须有这样的类,

public class DataAccessHolder
{
    private IDaoFactory daoFactory;
    private ILoader loader;
    ...
    public IDaoFactory DaoFactory
    {
        get { return daoFactory; }
        set { daoFactory = value; }
    }
    ...
}

在主类中,可以使用以下设计进行实例化

DataAccessHolder dataAccessHolder = new DataAccessHolder();
dataAccessHolder.DaoFactory = new NHibernateDaoFactory();
dataAccessHolder.Loader = new XMLLoader();
...
SamplePresenterClass s = new SamplePresenterClass(dataAccessHolder);

您对此设计有什么看法,或者您可以向我推荐一个不同的设计?

感谢所有回复者......

1 个答案:

答案 0 :(得分:1)

IMO,使用“全局”或静态daoFactory并使其更通用会更清晰。

DaoFactory<SamplePresenterClass>.Create(); // or
DaoFactory<SamplePresenterClass>.Create(id); // etc

然后,您可以定义DaoFactory<T>仅限于IDao

interface IDao
{
    IDaoProvider GetProvider();
}

interface IDaoProvider
{
    IDao Create(IDao instance);
    void Update(IDao instance);
    void Delete(IDao instance);
}

基本上,不是将每个构造函数传递给DaoFactory,而是使用静态泛型DaoFactory。它的T必须继承自IDao。然后DaoFactory类可以在运行时查看T提供程序:

static class DaoFactory<T> where T : IDao, new()
{
    static T Create()
    {
        T instance = new T();
        IDaoProvider provider = instance.GetProvider();

        return (T)provider.Create(instance);
    }
}

其中IDaoProvier是一个通用接口,您可以根据类使用XML,NHibernate,Web Services等来加载内容。 (每个IDao对象都知道如何连接到其数据提供者。)

总的来说,虽然设计并不差。添加更多OO,你将有一个漂亮的光滑设计。例如,XmlEnums的每个文件都可以实现为IDao

class Cat : IDao
{
    IDaoProvider GetProvider()
    {
        return new XmlLoader(YourEnum.Cat);
    }

    // ...
}