MVC中的模型和控制器之间的混淆

时间:2019-05-03 16:34:26

标签: model-view-controller

因此,我目前正在使用模型视图控制器体系结构来实现Java应用程序,但是在从服务器检索数据

如果我要创建一个包含数据的服务器的客户端模型将负责从服务器中检索数据,还是将其在这种情况下是控制者

例如,在 GUI 中,假设我输入了患者ID 453 ,而我想让应用程序查找患有以下疾病的患者的详细信息ID 453,在这种情况下,搜索操作是由模型还是由控制器执行?在当前的实现中,模型中有一个方法可以从服务器检索数据。

1 个答案:

答案 0 :(得分:0)

以最简单的形式,您可以说模型负责数据的表示。 MVC模式本身的定义没有区分模型是仅应充当数据结构还是应包含算法/逻辑来检索/更新/创建数据存储中的数据表示形式(例如,数据库)。

各种来源之间Model的定义中肯定有歧义。例如,如果您在维基百科[1]中查找MVC设计模式,则会遇到以下模型定义:

  

图案的中央部分。它是应用程序的动态数据结构,独立于用户界面,它直接管理应用程序的数据,逻辑和规则。

然后,如果您查看诸如this one之类的其他来源,则它在某种程度上与Wikipedia的定义相矛盾,因为它不包含任何逻辑,而纯粹是数据的表示。

根据我在企业应用程序上的工作经验,虽然我不会评论哪种定义正确,但我几乎可以告诉您,当我们在谈论Model体系结构时说MVC时,人们通常将其称为数据的表示形式。换句话说,他们正在谈论数据的结构。而且我相信这是思考模型对象的正确方法。

以您的Patient模型为例,这将是一个POJO,它具有最简单形式的private fieldsgetterssetters

public class Patient {
    private int id;
    private String name;
    ...
    // more properties

    public int getId() {
        return this.id;
    }

    public String getName() {
        return this.name;
    }

    public void setId(int id) {
        this.id = id;
    }

    public void setName(String name) {
        this.name = name;
    }

由于您提到要从服务器检索数据,因此我假设数据存储在某个数据库中。因此,根据用于将域模型(也称为模型对象)连接/映射到数据库中它们的表示方式的技术(例如Hibernate / Open JPA),您将向模型类添加注释告诉对象关系映射器(ORM)模型对象中的特定字段映射到数据库中表中的特定列。或者,根据库的不同,您最终可能还会使用XML配置来进行映射。 这样,您就可以在Model应用程序中创建MVC

那么您将在此模型上执行CRUD操作所需的所有逻辑/算法放在哪里?像在您的示例中检索ID为453的Pateint一样?欢迎使用存储库模式[1][2]。因此,Repository Pattern包含用于检索数据的逻辑。在您的示例中,对患者的搜索(相当于从数据库中检索患者数据)将存在于存储库层或更常见的数据访问层中。

在Java世界(至少使用Web技术)中,Java Persistence API定义了由多个提供商(如Hibernate,OpenJPA)实现的查询模型。这就是在存储库层中使用的东西。在此层中,您添加了搜索逻辑。

JPA规范的大多数实现已经带有一些默认API,以对模型对象执行简单的CRUD操作。我曾与Spring合作,在您的Patient示例中,存储库如下所示:

public interface PatientRepository extends JpaRepository<Patient, Long> {
}

就这样。如果您查看javadoc中的SimpleJPARespoitory,则已经可以访问诸如findById之类的方法的默认实现。现在,您可以在Controller中注入/引用PatientRepository的实例并访问数据。我们将在下一部分中解决这个问题。

那么控制器将要做什么? 在最笼统的术语中,Controller就像是您的应用程序的入口点。实际上不是。因为它实际上来自Java Servelet API(对于Web应用程序)的servlet,它实际上将控件传递给了Controller。但是从高层次的理解角度来看,您可以将控制器视为接收请求的控制器。一旦接收到该请求,它就会像存储库一样调用以下层,该层使用必须从数据源获取数据并构建Model对象并将其提供给Controller的逻辑。 因此,在您的示例中,PatientController看起来像这样(在Spring框架中)

@RestController
@RequestMapping("/patients")
public interface PatientController {

    @GetMapping("/{id}")
    Pateint getPatient(@PathVariable int id);
}

以及您的REST控制器的实现:

@Component
public class PatientControllerImpl implements PatientController {

    @Autowired
    PatientRepository pateintRepository;

    @Override
    public Patient getPatient(int id) {
        Patient patient = patientRepository.findById(id);
        return pateint;
    }
}

因此,如果您调用服务器上运行的应用程序以获取患者ID 453的患者详细信息,则类似于:

http://localhost:8080/patients/453

然后,它被控制器接收,并且getPatient方法被调用。然后,它调用findById的{​​{1}}方法,该方法将与数据库对话,获取ID = 453的患者详细信息,构造PateintRepository模型对象,然后返回到Controller。

然后,控制器将此Model对象绑定到视图,并将其以请求的任何形式传递回客户端。

这当然不会显示所有最佳实践。但是应该让您很好地了解所有部件在哪里以及如何组装在一起。

关于构建MVC应用程序的文章很多。我建议您从演示Spring MVC应用程序开始。 我还建议您阅读有关构建Web应用程序的经典3层体系结构。了解这一点后,您将能够对MVC有所了解。