views:

347

answers:

1

I'm working on a business application which is being developed using DDD philosophy. Database is accessed through NHibernate and data layer is implemented using DAO pattern.

The UML class diagram is shown below.

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

I don't know the design is good or not. What do you think?

But the problem is not the design is good or not. The problem is,

After starting up the application an IDaoFactory is instantiated in presentation layer and send as parameter to presenter classes(which is designed using MVC pattern) as below

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

Using just one data provider (which was just one database) was simple. But now we should get data from XML too. And next phases of the development we should connect to different web services and manipulate incoming and outgoing data.

The data from XML is going to be got using a key which is an enum. We add a class named XMLLoader to the data layer and add an interface ILoader to the domain. XMLLoader has a method whose signature is

List<string> LoadData(LoaderEnum key)

If we instantiate ILoader with XMLLoader in presentation layer as below we have to send it to objects which is going to get some XML data from data layer.

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

After implementing web service access classes

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

The parameters is going to be grown in time. I think i can hold all instances of data access objects in a class and pass it to required presenters (maybe singleton pattern can helps too). In domain layer there must be a class like this,

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

In main class the instantiation can be made with this design as follows

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

What do you think about this design or can you suggest me a different one?

Thanks for all repliers...

A: 

IMO, it would be cleaner to use a "global" or static daoFactory and make it generic.

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

Then, you can define DaoFactory<T> to take only, say, IDao's

interface IDao
{
    IDaoProvider GetProvider();
}

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

Basically instead of passing every constructor your DaoFactory, you use a static generic DaoFactory. Its T must inherit from IDao. Then the DaoFactory class can look at the T provider at runtime:

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

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

Where IDaoProvier is a common interface that you would implement to load things using XML, NHibernate, Web Services, etc. depending on the class. (Each IDao object would know how to connect to its data provider).

Overall, not a bad design though. Add a bit more OO and you will have a pretty slick design. For instance, each file for the XmlEnums could be implemented as IDao's

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

    // ...
}
SoloBold
I read it over and over but can't get it. What is the purpose of DaoFactory<T> and GetProvider?As i said i have to use all of the providers. Some data is going to be written to database, some of them is going to be read from XML files etc
As shown in image IDao has GetByID, Save, etc. These aren't needed in XMLLoader or web service providers.
SamplePresenterClass is a Presenter class in MVP pattern. It delegates jobs to a service class and also it sends the daoFactory instance to the service class. I still can't get theseDaoFactory<SamplePresenterClass>.Create(); // orDaoFactory<SamplePresenterClass>.Create(id); // etc