因此,我目前正在使用模型视图控制器体系结构来实现Java应用程序,但是在从服务器检索数据。
如果我要创建一个包含数据的服务器的客户端,模型将负责从服务器中检索数据,还是将其在这种情况下是控制者?
例如,在 GUI 中,假设我输入了患者ID 453 ,而我想让应用程序查找患有以下疾病的患者的详细信息ID 453,在这种情况下,搜索操作是由模型还是由控制器执行?在当前的实现中,模型中有一个方法可以从服务器检索数据。
答案 0 :(得分:0)
以最简单的形式,您可以说模型负责数据的表示。 MVC模式本身的定义没有区分模型是仅应充当数据结构还是应包含算法/逻辑来检索/更新/创建数据存储中的数据表示形式(例如,数据库)。
各种来源之间Model
的定义中肯定有歧义。例如,如果您在维基百科[1]中查找MVC设计模式,则会遇到以下模型定义:
图案的中央部分。它是应用程序的动态数据结构,独立于用户界面,它直接管理应用程序的数据,逻辑和规则。
然后,如果您查看诸如this one之类的其他来源,则它在某种程度上与Wikipedia的定义相矛盾,因为它不包含任何逻辑,而纯粹是数据的表示。
根据我在企业应用程序上的工作经验,虽然我不会评论哪种定义正确,但我几乎可以告诉您,当我们在谈论Model
体系结构时说MVC
时,人们通常将其称为数据的表示形式。换句话说,他们正在谈论数据的结构。而且我相信这是思考模型对象的正确方法。
以您的Patient
模型为例,这将是一个POJO,它具有最简单形式的private fields
和getters
和setters
。
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有所了解。