MVC数据源:控制器还是模型?

时间:2012-01-13 19:18:53

标签: model-view-controller oop activerecord datamapper

一个简单的问题:在OOP MVC应用程序中,一个关键原则是责任分离。因此,我认为模型和从数据库,文件,xml,webservice等获取模型的对象应该与模型本身分开。例如,这可以通过实现数据映射器来完成。

但是,当我有一个可以从不同来源加载的模型时,我该怎么办?模型应该负责数据源,还是由控制器负责?

一个简单的例子可以是可以从数据库或文件加载的配置类。控制器是否应该指示数据源,或模型是否应该知道何时从数据库或文件加载配置信息?

3 个答案:

答案 0 :(得分:0)

使用框架的数据源是由控制器MachII,Model-Glue(Coldfusion框架)以及模型层(ColdSpring)提供的 - 如Java中的Spring。

我认为关键是要使用对你更有意义的东西,保持耦合最小化并保持一致,这意味着不要将数据源或对象依赖放在多个位置。

您还可以考虑使用服务类型对象来抽象数据源并让它为任何人提供服务。

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>

您可以通过控制器中定义的args查看args指定的不同数据源。

答案 1 :(得分:0)

根据您的情况和反应,我建议调查依赖注入。然后,您可以根据要让它确定的任何变量集来确定要使用哪个数据源。这是我使用多个数据源并希望通过我选择的某些预定因素确定数据源时使用的内容。

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;
}

答案 2 :(得分:0)

我在Coldbox中这样做的方式是在模型中使用CB的INJECT方法。在构造函数的cfargument中,我指定:

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

这是在coldbox.cfc文件中指定dsn并将其命名为“dsn”。我保持通用,所以我可以将这些东西复制到其他项目,只需要更改coldbox.cfc中的DSN名称。

但是在这样做之后,你会得到这样的dsn:

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

我希望这有帮助,至少有一点。

罗布