Источник данных MVC: контроллер или модель? - PullRequest
2 голосов
/ 13 января 2012

Простой вопрос: в приложении ООП MVC одним из ключевых принципов является разделение обязанностей. Поэтому я считаю, что модель и объект, извлекающий модель из базы данных, файла, XML, веб-службы и т. Д., Должны быть отделены от самой модели. Это может быть сделано, например, путем реализации datamapper.

Однако, что мне делать, если у меня есть модель, которую можно загрузить из разных источников? Должна ли модель отвечать за источник данных или это ответственность контроллера?

Простым примером может быть класс конфигурации, который может быть загружен из базы данных или файла. Должен ли контроллер указывать источник данных или модель должна знать, когда загружать информацию о конфигурации из базы данных или файла?

Ответы [ 3 ]

0 голосов
/ 13 января 2012

Исходя из вашей ситуации и ответа, я бы посоветовал изучить внедрение зависимости.Затем вы можете позволить ему определять, какой источник данных использовать, основываясь на любом наборе переменных, по которому вы хотите, чтобы он определял вещи.Это то, что я использую, когда у меня есть несколько источников данных, и я хочу, чтобы источник данных определялся некоторыми заранее определенными факторами, которые я выбрал.

http://en.wikipedia.org/wiki/Dependency_injection

Что касается того, кто должен осуществлять инъекцию,Я оставляю это фабрике репозитория и просто спрашиваю интерфейс в контроллере.Затем фабрика на основе внедрения зависимостей определяет, какой репозиторий предоставить.

Пример:

Внедрение зависимостей в глобальный класс инфраструктуры:

Bind<INewsArticleRepository>().ToMethod(context => NewsRepositoryFactory.Create((NewsRepositoryFactory.RepositoryType)Enum.Parse(typeof(NewsRepositoryFactory.RepositoryType), ConfigurationManager.AppSettings["NewsArticleRepositoryProvider"])));

Фабрика репозитория

public static INewsArticleRepository Create(RepositoryType type)
    {
        switch (type)
        {
            case RepositoryType.Mock:
                return new MockNewsArticlesRepository();
            case RepositoryType.Sql:
                return new SqlNewsArticleRepository();
            default:
                throw  new NotImplementedException();
        }
    }

Вызовите контроллер для хранилища

private INewsArticleRepository newsItemRepository;

public NewsController(INewsArticleRepository newsItemRepository)
{
    this.newsItemRepository = newsItemRepository;
}
0 голосов
/ 14 января 2012

В Coldbox я использую метод INJECT CB в модели.В аргументе конструктора я указываю:

<cfargument name="dsn" type="any" inject="coldbox:datasource:dsn">

И это от указания dsn в файле coldbox.cfc и вызова его "dsn".Я держу его в общих чертах, чтобы я мог скопировать этот материал в другие проекты, и мне нужно только изменить имя DSN в coldbox.cfc.

Но после этого вы получите dsn, например:

variables.dsn = arguments.dsn.getName();

Надеюсь, это поможет, хотя бы немного.

Роб

0 голосов
/ 13 января 2012

использовали фреймворки, в которых источник данных сообщается контроллером MachII, Model-Glue (фреймворки Coldfusion), а также из уровня модели (ColdSpring) - как Spring в Java.

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

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

Этот файл IOC может выглядеть следующим образом:

<?xml version="1.0" encoding="UTF-8"?>

<beans>

  <bean id="chartShareObj" class="model.charts.ChartShared" autowire="byType" />
  <bean id="trendChartObj" class="model.charts.TrendChart" autowire="byType" />

  <bean id="adminRightsDA0" class="org.datamentor.institution.RightsDAO">
    <constructor-arg name="dsn">
      <value>${dsn_dm}</value>
    </constructor-arg>
  </bean>

  <bean id="assessmentManager" class="model.assessment.Manager">
    <constructor-arg name="dsn">
      <value>${dsn_au}</value>
    </constructor-arg>
  </bean>

</beans>

Вы можете увидеть различные источники данных, заданные аргументами через аргументы, определенные в контроллере.

...