Доступ к нескольким поставщикам данных на уровне данных - PullRequest
1 голос
/ 28 октября 2008

Я работаю над бизнес-приложением, которое разрабатывается с использованием философии DDD. Доступ к базе данных осуществляется через NHibernate, а уровень данных реализован с использованием шаблона DAO.

Диаграмма классов UML показана ниже.

Диаграмма классов UML 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. И на следующих этапах разработки мы должны подключаться к различным веб-сервисам и манипулировать входящими и исходящими данными.

Данные из XML будут получены с использованием ключа, который является enum. Мы добавляем класс с именем XMLLoader на уровень данных и добавляем интерфейс ILoader в домен. XMLLoader имеет метод, подпись которого

List<string> LoadData(LoaderEnum key)

Если мы создаем экземпляр ILoader с XMLLoader на уровне представления, как показано ниже, мы должны отправить его объектам, которые собираются получить некоторые данные XML из уровня данных.

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

После реализации классов доступа к веб-сервисам

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 Ответ

1 голос
/ 28 октября 2008

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, веб-служб и т. Д. В зависимости от класса. (Каждый объект IDao будет знать, как подключиться к своему поставщику данных).

В целом, дизайн неплохой. Добавьте немного больше ОО, и вы получите довольно гладкий дизайн. Например, каждый файл для XmlEnums может быть реализован как IDao

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

    // ...
}
...