【问题标题】:Should model objects be created by view in MVC pattern? [closed]模型对象是否应该由 MVC 模式中的视图创建? [关闭]
【发布时间】:2013-07-18 04:40:35
【问题描述】:

在 MVC 模式中,我看到了构成数据模型的类和驱动系统的这些类的实例之间的区别。我的团队不同意我的观点,我想澄清一下。

我有一个 Employee 类,它是模型中唯一的类。控制器具有该类的一个实例,该实例驱动视图。

我会将控制器拥有的Employee 类的一个实例称为“模型”,而将不驱动系统的Employee 类的任何其他实例称为“不是模型” .

我之所以做出这种区分是因为我的团队认为视图不应该创建模型。我同意,但我认为视图应该能够创建 Employee 类的实例以传递给控制器​​。

例如,如果我在控制器中有一个方法 setCoworker(employee : Employee),我认为视图创建一个 Employee 的新实例并将其传递给控制器​​是完全可以的。

MVC 模式的最佳实践规定了什么?我不应该从视图中创建实例吗?

【问题讨论】:

    标签: design-patterns model-view-controller


    【解决方案1】:

    这在一定程度上取决于您所遵循的哪种 MVC 模式(有很多风格)。不过,一般来说,View 的唯一职责应该是将人类输入转换为对 Controller 的调用,并将 Model 保存的任何数据状态转换为输出给人类。

    所以我必须同意你的团队。您可能在视图中有一个按钮 OnClick 处理程序等,然后调用 controller.BuildANewModel(),但您不会让视图自己实例化新模型。

    也就是说,上次我检查时,四人组已经挂了他们的棒球棒和轮胎铁杆,并且不打算对那些不遵守模式的人进行打击,所以任何对你有用的东西。 . . :)

    【讨论】:

    • 感谢您的想法。但是,如果 BuildANewModel() 需要大量直接来自人工输入(即视图)的参数怎么办?我们可以将所有参数传递给函数,但这变得难以管理,如果我们创建一个包含所有参数的单独对象,我们基本上会重复一个已经在模型中的类。你怎么看?
    • 这通常在控制器的接口中定义,作为参数或某种数据对象。就像我说的那样,没有人会因为将模型用于该数据对象而打破你的膝盖,但这不符合模式,这就是你的问题所在。
    • 我有点喜欢控制器公开数据对象的想法。像EmployeeCreationArgs 这样的东西。如果视图不关心或不应该关心 Employee 类的某些部分,这可能很有价值。感谢您的意见:)
    【解决方案2】:

    我同意你的团队:

    为了限制依赖关系,视图甚至不应该知道控制器及其内部实现,因此它无法将创建的员工传递给控制器​​。
    应该只有一个通知机制——委托或其他一些松散耦合机制——视图通知控制器,它应该创建一个新员工,或者不同的措辞:视图将通知控制器一些特定的输入或事件和控制器将决定创建一个新员工。
    在您的解决方案中,视图和控制器将紧密耦合在一起,实际上可以将其视为组件:MVC 模式将被破坏。


    MVC 简而言之:模型保存数据,控制器处理逻辑,视图与用户交互。唯一知道彼此的组件是控制器。模型对视图或控制器一无所知,视图对模型一无所知,并且仅与控制器非常松散地耦合。只是通知它有关输入和类似的信息。您当然可以创建其他构造,但这不再是 MVC。你的问题是关于 MVC 的。

    这描述了Cocoa中的MVC Pattern,词汇可能不熟悉,但MVC或多或少应该是这样的。绿色表示控制器对模型和视图的了解,而黄色表示不同的松散耦合机制。这在不同的语言和框架中可能会有所不同。

    在这里找到:What should own the model in an MVC pattern?

    【讨论】:

    • 方法调用并不意味着视图耦合到控制器的内部实现。您可以使用接口来抽象向视图公开的控制器的行为。视图不耦合到接口的任何特定实现。这并不能回答我关于模型的具体问题。
    • 当然,接口是一个很好的解决方案。但如果视图将成为新对象的创建者,它将完成属于控制器的任务。因此它将包含控制器所依赖的代码:控制器将分散在多个对象中。
    • 您能阅读我对 Paul 帖子中关于传递参数的第一条评论吗?您对此有何看法?
    • 你也可以创建一个工厂,独立于你的控制器和视图。但我仍然会说视图应该只与控制器对话并且不应该创建任何内容。
    • 对不起,我不得不说:你应该花更少的时间来证明你的模型创建视图和退化控制器的想法,并听取你的团队的意见。 MVC 简而言之:模型持有数据,控制器持有逻辑,视图与用户交互。唯一知道彼此的组件是控制器。模型对视图或控制器一无所知,视图对模型一无所知,并且仅与控制器非常松散地耦合。只是通知它有关输入和类似的信息。您当然可以创建其他构造,但这不再是 MVC。你的问题是关于 MVC 的。
    【解决方案3】:

    视图不应向控制器传递任何内容。控制器不应该向视图传递任何东西。模型层不应该向控制器返回任何东西。以下是在 MVC 中应该如何实现信息流:

    来源:wikipedia

    另外,模型是一个层。不是类或对象。包含多个结构的层,每个结构都有不同的职责。你所说的Employee 不是模型(甚至不是“模型”)。相反,它只是众多domain objects 之一。

    您的视图和控制器都不应该直接访问域对象。相反,它们应该通过服务层与模型层交互,服务层包含模型层内的“应用程序逻辑”(域和存储结构之间的交互)。

    这将是我在这个主题上的两分钱,但我会将此标记为“过于宽泛”,因为人们可以写一本关于 MVC 实现主题的书(而且有些书有)。

    【讨论】:

    • 只是一个帮助人们避免混淆的注释 - 这是 classical MVC。例如,Backbone.js 在更广泛的意义上使用“视图”,这种“视图”确实将所有用户交互传递给其他组件。
    • @DmitriZaitsev Backbone 与主题有何关系?
    • 在迂腐方面我理解你。但是人们通常用 MVC 来指代各种风格。 Backbone 只是一个示例,用于说明其他风格的观点,可能与困惑的读者相关,也可能不相关,但随后另一个库或框架可能会。
    猜你喜欢
    • 2011-10-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-17
    • 2011-04-12
    • 1970-01-01
    相关资源
    最近更新 更多