IoC / SRP дизайн проблема - PullRequest
       45

IoC / SRP дизайн проблема

0 голосов
/ 18 февраля 2012

Я разрабатываю систему, которая предоставляет веб-сервис для доступа к своей базе данных и предоставляет его через классы .NET. Наш обычный способ работы - создавать экземпляр класса веб-службы всякий раз, когда нам нужно получить доступ к базе данных и напрямую использовать этот экземпляр; это, конечно, полностью идет вразрез с IoC и создает в основном непроверяемый код. Сейчас я пытаюсь разработать новый стандартный способ работы с использованием IoC, чтобы позволить нам писать (более) твердотельный код.

Мое текущее решение таково (не очень хорошо объяснено):

Веб-служба заключена в класс DatabaseConnection, который хранит объект веб-службы в качестве защищенного члена и обеспечивает доступ к ряду часто используемых общих вызовов базы данных.

Когда мне нужен доступ к базе данных в реальном приложении, я наследую этот класс (вызывая новый класс, скажем, ApplicationDatabaseConnection) и реализую необходимые взаимодействия с базой данных в методах, которые затем могут вызывать веб-службу.

Этот класс не используется непосредственно в приложении, но предоставляет интерфейсы "соединителя" для различных частей приложения, каждая из которых представлена ​​моделью контроллера / представления, подобной классу на верхнем уровне. Всякий раз, когда вызывается одна из этих прикладных функций (например, из пользовательского интерфейса), создается соответствующий объект контроллера и передается мой объект ApplicationDatabaseConnection в качестве реализации соответствующего интерфейса «соединителя», поэтому доступ к базе данных должным образом инкапсулируется и отсоединяется в этой точке. насколько я могу судить.

Моя проблема с этим заключается в следующем: хотя это первый случай, когда я нашел фактическое использование ISP (принцип разделения интерфейса) в своем собственном коде (хотя я далеко не уверен, действительно ли это разумное использование концепции), Я боюсь, что этот класс может сделать слишком много и нарушить SRP (принцип единой ответственности). Или «только предоставление доступа к базе данных, хотя и для нескольких разных потребителей» является одной обязанностью?

Чтобы сделать это немного яснее, примерно так будут выглядеть соответствующие классы:

DatabaseConnection
    protected m_webservice
    public OftenUsedDatabaseAccess()

ApplicationDatabaseConnection : DatabaseConnection, IConnectorA, IConnectorB
    public IConnectorA.RetrieveRecords(fieldValue)
    public IConnectorB.WriteStuff(listOfStuff)

FunctionAController
    private m_IConnectorA

FunctionBController
    private m_IConnectorB

Альтернативы, которые я могу придумать, мне тоже не кажутся идеальными.

Чтобы разделить функциональные возможности доступа к базе данных, класс ApplicationDatabaseConnection может быть только фабричным классом с Create методами для различных соединителей (за интерфейсами IConnectorAFactory, IConnectorBFactory) - но на самом деле ничего там нет необходим заводской шаблон; я ничего не знаю только при создании экземпляров объектов "контроллер".

Кроме того, фактические классы соединителей, по сути, также должны быть производными от DatabaseConnection, потому что им нужны одинаковые базовые способности, и тогда (не позднее) вся конструкция становится довольно зловещей.

Я полагаю, что в какой-то момент я ошибся, и теперь совершенно на неправильном пути. Как должна выглядеть структура такого решения? Будем очень благодарны за любой толчок в правильном направлении.

Edit:

@ Ответ Тобиаса заставил меня осознать, что я забыл важную деталь: есть две разные версии веб-службы с почти одинаковыми возможностями, но совершенно разными API, и это одна из причин, по которой у есть быть инкапсулированным.

Еще одно: если мои логические классы обращаются к веб-сервису напрямую (или через интерфейс), они также занимаются построением запросов веб-сервиса во всех деталях, что делает гораздо более тесно связанный код (тот, который мы до сих пор производил) и нарушает SRP - отсюда идея интерфейса соединителя.

Ответы [ 2 ]

0 голосов
/ 24 сентября 2012

Много месяцев спустя я знаю, что подход «ApplicationDatabaseConnection» не только нарушает SRP, но также и OCP, в то же время препятствуя модульности.- «основной» объект DatabaseConnection относится к подклассу, который также имеет метод «Create», который принимает фабрики для определенных производных DatabaseConnection и не заботится о том, что именно он создает.Таким образом, каждый контроллер может запросить свой собственный объект подключения, и можно добавить контроллеры, о которых основное приложение не знает (например, через MEF).

0 голосов
/ 18 февраля 2012

Почему бы просто не создать интерфейс, такой как MyWebService, и внедрить его в MyWebServiceImpl, который вызывает ваш сервис? Может выставить те же методы, что и ваш сервис, и просто делегировать ему ...

...