我应该在MVC的哪里放置API请求?


25

我正在使用MVC模式构建Web应用程序。遵循这种架构,我们可以看到模型中使用了与数据库交互的所有方法。

但是,如果我必须打电话给其他人在网络上公开的服务会怎样?例如,我想访问Facebook API以获取页面的所有关注者,那么,将这些方法放在哪里?

显然,视图不是一个好主意,因为该模块专用于表示,不应使用控制器来检索数据,而模型通常仅用于与数据库的交互。

那么,您能给我一些提示吗?而且,请问我是否对MVC架构犯了一些错误?


2
我认为,如果您列出了用于支持MVC应用程序的某些库和框架,人们将能够提供更好的答案。尽管MVC模式与技术无关,但并非所有框架都明确遵循它。此外,大多数成熟的框架已经具有出色的文档,并且知道您使用的是哪个框架,将使您更容易将自己引向遵循您思路的既有解释。
2015年

2
数据库?数据源?它只是数据。

2
关于“ MVC”应该是什么的观点如此之多,以至于这个问题太抽象了,无法回答。
RemcoGerlich 2015年

2
另外,请考虑从前端Javascript代码调用API,并且不要让它完全触及后端“ MVC”内容。
RemcoGerlich 2015年

@Remcogerlich这就是为什么我提议增加他正在查看的实际实现的原因。他可能正在处理mvc的后端和前端实现。我们也可以采用另一种模式来更好地解释这些差异。
2015年

Answers:


37

该模型不限于与数据库交互,该模型负责获取和处理数据。

因此,对于您的视图和控制器而言,如果数据来自数据库或Web服务,甚至是完全随机的,则应该没有区别,因此您应该在模型中进行处理。

MVC是一种表示模式,仅分隔不同的表示层。

这并不意味着该模型必须是统一的意大利面条代码。您的模型本身也可以分层,但是控制器不应该知道数据来自何处。

模型中的公共方法可以采用以下结构(伪代码),可以由控制器调用:

public MyDataClass getData(int id) {
    WebServiceData wsData = WebService->getData(id);
    DatabaseData dbData = ORM->getData(id);
    return new MyDataClass(wsData, dbData);
}

WebService并且ORM可能需要接口的实例,可以通过依赖注入将其替换为模拟,但是您的控制器和视图不必出于测试目的而更改。


8
该模型不应具有任何逻辑,因此不应直接与任何事物交互。MVC模式显然要求将所有逻辑放入控制器中。这些控制器应联系数据库,API等,并根据需要更新模型。这使您的模型技术不可知,并确保它仅充当存储机制,可以将其传递给各种视图以进行表示,并传递给控制器​​进行其他操作。
2015年

3
@CLW:模型!=数据模型。更多详细信息可以在其他地方找到,例如stackoverflow.com/a/14045514/124983
Residuum 2015年

2
@CLW:业务逻辑不应使用M,V C。模型是数据存储的抽象,视图和控制器是您的用户界面。它们是您正在构建的实际应用程序的外围,应该只是“代码”,而不必了解数据库和Web之类的内容。
RemcoGerlich 2015年

2
“模型”部分有数百种不同的解释方式。我总是被教导说模型是一种表示。模型火车是真实火车的表示,几乎没有运动的零件像真实火车一样运动。同样,您应用中的模型代表了您正在构建要替换的软件的系统和流程。因此,模型具有行为。该行为包含您的“业务逻辑”。因此,当你忽略纯CRUD的数据访问,用户界面和互操作,还剩下些什么可能是你的“模式” -域名类别,业务规则等
阿那克西曼德

1
@RemcoGerlich我没有谈论任何有关业务逻辑的内容。我只是简单地说,由于大多数对MVC的解释都要求模型仅是代表您的应用程序状态的简单结构,因此联系DB,API等的责任不应放在模型中,因为应该无逻辑。与数据库进行通信的职责应该落在控制器上或由控制器管理的另一个对象上。
2015年

12

关于M,V和C有一个常见的(故意的)误解。不是他们扮演的角色,而是他们什么。

在MVC的原始桌面GUI定义中,它们是modules。通常,一个应用程序具有多个视图,有时在三胞胎中工作,有时具有多种视图和模型,一些控制器可以将它们混合和匹配。

在OTOH的Web框架中,它们往往被看作是,它们只是其中的一层,并且主要涉及覆盖一些底层抽象层:“模型层对数据库进行抽象”,“视图层实现表示”,“控制器”层处理用户输入”。

因此,我想说您已经有一个专门用于与数据库交互模型,现在只需创建另一个模型来处理您的源API。如果使它们尽可能相似,则大多数控制器和视图代码都可以与任一模型无缝地协同工作。


1
同意:模型始终被认为是整个问题领域。在复杂的应用程序中,通常应该将其作为大部分代码。它们由如果您更改用户界面(例如,从网站到GUI甚至是命令行应用程序)都不会更改的所有代码组成。想一想编译器。如果您从命令行用户界面转到GUI,甚至是Web UI,则只有很少一部分代码会更改。这样的应用程序的所有胆量都是模型。
凯文·卡斯卡特

1
在最初的Smalltalk用法中,界面中的每个UI控件都有其自己的模型,视图和控制器。
RemcoGerlich 2015年

5

对MVC进行任何讨论的部分困难在于,不同的群体选择了它来表示不同的意思。例如,在Rails应用程序中使用的MVC的实现对于编写Swing应用程序的人来说几乎是无法识别的。在某种程度上,MVC仍然是一个定义明确的事物,它更多是一组指导原则(将核心应用程序与其视觉表示分开,提供了灵活的机制以使两者融合在一起),可以通过各种方式实现方法。

确实,有一种趋势是给不同的MVC衍生的设计赋予不同的名称(有关问题的讨论,请参见Martin Fowler的本文),甚至放弃精确的命名-例如,AngularJS将自己描述为Model-View-Whatever框架。

因此,如果不知道您正在使用哪个版本的“ MVC”,就很难回答。但是,API请求通常是核心应用程序的一部分(如果您决定使用其他视觉表示,则该部分不应更改),在许多实现中,该请求将完全包含在模型中。


2

在这里,模型描述如下:

模型存储检索到控制器并显示在视图中的数据。每当数据发生更改时,控制器都会对其进行更新。

我想说的是,控制器要么包含调用服务的逻辑,要么调用单独的Service对象。如果服务是单独的,则可以更轻松地创建测试,例如,如果无法通过网络连接到服务,则某些服务TestService可以提供Service本地响应。

还要检查出这个暗示控制器调用服务的答案。


2

您的模型不应包含任何实际代码,而应被视为更多消息或结构,用于管理由控制器操纵并由视图显示的内容。

您的控制器应负责联系任何API,数据库,服务等,以请求更改并管理对模型的任何必要更新。

MVC模式的全部优势在于,它使逻辑(控制器)与视图和状态(模型)脱钩。这样一来,您就可以确保只有控制器中的代码才能产生副作用,因为视图和模型完全不允许更改。

它还可以更好地重用代码,因为可以在各种控制器和视图之间共享模型。


4
我认为当您在此处说“模型”时,是指“视图模型”,这与IMO是分开的。一个视图模型从控制器到视图获取数据,因此要么是视图的实现细节,要么是视图与控制器之间通信的一个方面(实际上并不适合)(取决于您如何看待它)。MVC中的“模型”是指系统模型-包含其数据,结构和行为的系统表示。模型是状态和逻辑。当操作视图时,控制器是导致逻辑运行和状态改变的原因。
anaximander 2015年

@anaximander不,我是在对MVC的相当严格的解释中指的是模型(请参阅Wikipedia,Microsoft MVC,Head First Design模式等)。在这些情况下,模型不过是用于传递数据的简单结构而已周围没有视图模型之类的东西。尽管Microsoft MVC实现的确为模型添加了各种属性,但这比起其他任何事情都更加方便。最后,MVC模式的目的是促进代码分离的良好实践并限制副作用。
2015年

1

可能还差得远,但这是我对WebApp以及在许多情况下使用[复杂]远程API的看法:

我将其设为类(即数据缓解方法的库),而不是模型(即数据缓解功能的堆栈)。似乎它的作用更加透明,与逻辑/模式无关,并且您可以在任何地方使用它,而无需加载->每次要使用它时都调用模型/控制器本身。逻辑仍然是分开的,数据点仍然很灵活,在一些奇怪的情况下(例如,堆叠clientAJAX-> appJSON-> appLIB-> remoteAPI-> remoteJSON等以间接轮询端点),互操作性似乎更加开放。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.