MVC设计模式
MVC设计模式是Web应用程序中最古老的体系结构模式之一。
MVC代表模型视图控制器。
MVC设计模式用于以独立单位将程序中不同层的逻辑分开。
这就是关注点分离的原理。
MVC设计模式
使用MVC设计模式,我们具有设计所依赖的以下组件:
从一层转移到另一层的模型。
视图负责显示应用程序中存在的数据。
控制器负责接受来自用户的请求,修改模型并将其发送到显示给用户的视图。
MVC模式背后的想法是,在代表真实世界实体的域对象和我们在屏幕上看到的表示层之间非常清晰地分离。
域对象应完全独立,并且也应在没有View层的情况下工作。
在本程序中,我们将尝试使用Spring Boot应用程序在View层中使用Thymeleaf建立一个强大的MVC示例。
MVC应用架构
在开始构建应用程序之前,构建结构始终是一个好主意。
基于MVC模式,我们的应用程序中将包含以下几层:
MVC模式示例
当我们将基于MVC模式构建Spring Boot应用程序时,我们首先创建一个基于Maven的项目,并向其中添加与Spring Boot相关的依赖项。
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.7.RELEASE</version> <relativePath <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build>
现在,让我们开始定义模型。
MVC模型
让我们开始定义各个部分,然后首先使用我们的模型。
示例应用程序的第一步是定义我们的Model类:
package com.theitroad.mvcpattern.model; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; @Entity public class Person { @Id @GeneratedValue private Long id; private String name; private int age = 0; //standard getters and setters }
这是一个简单的模型类,可以包含一个人的信息。
让我们在Controller and Service中使用定义的模型。
MVC控制器
现在我们知道要在模型中传输什么数据,让我们定义一个控制器以允许用户请求此数据:
package com.theitroad.mvcpattern.controller; import com.theitroad.mvcpattern.model.Person; import com.theitroad.mvcpattern.service.PersonService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; @Controller public class PersonController { @Autowired PersonService personService; @RequestMapping(value = "", method = RequestMethod.GET) public String greetingForm(Model model) { model.addAttribute("person", new Person()); return "greeting"; } @RequestMapping(value = "/person", method = RequestMethod.POST) public String addPerson(Model model, @ModelAttribute Person person) { personService.createPerson(person); model.addAttribute("people", personService.getAllPersons()); return "result"; } }
在上面的控制器中,我们定义了两个API:
该应用程序的基本URL展示了一个我们接下来设计的简单视图。
应用程序的"/person" URL提供了一个简单的视图,该视图将人员数据制成表格。
我们将在一分钟内看到视图。
在此之前,我们还需要提供服务和存储库层。
package com.theitroad.mvcpattern.service; import com.theitroad.mvcpattern.model.Person; import java.util.List; public interface PersonService { Person createPerson(Person person); List<Person> getAllPersons(); }
接口实现如下所示:
package com.theitroad.mvcpattern.service; import com.theitroad.mvcpattern.dal.PersonRepository; import com.theitroad.mvcpattern.model.Person; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; @Service public class PersonServiceImpl implements PersonService { @Autowired private PersonRepository personRepository; @Override public Person createPerson(Person person) { return personRepository.save(person); } @Override public List<Person> getAllPersons() { return personRepository.findAll(); } }
最后,在DAL层中,存储库接口如下所示:
package com.theitroad.mvcpattern.dal; import com.theitroad.mvcpattern.model.Person; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; @Repository public interface PersonRepository extends JpaRepository<Person, Long> { }
优秀!既然我们已经完成了所有服务和数据库访问逻辑,那么我们终于可以尝试使用View了。
MVC视图
最后,让我们放置好视图。
我们首先在src/main/resources/templates目录中定义我们的greetings.html页面。
<!DOCTYPE HTML> <html xmlns:th="https://www.thymeleaf.org"> <head> <title>Spring Boot MVC</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" </head> <body> <h1>Add new person</h1> <form action="#" th:action="@{/person}" th:object="${person}" method="post"> <p>Name: <input type="text" th:field="*{name}"</p> <p>Age: <input type="number" th:field="*{age}"</p> <p><input type="submit" value="Submit" <input type="reset" value="Reset"</p> </form> </body> </html>
接下来,我们还定义" result.html"页面:
<!DOCTYPE HTML> <html xmlns:th="https://www.thymeleaf.org"> <head> <title>Spring Boot MVC</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" </head> <body> <div th:if="${not #lists.isEmpty(people)}"> <h2>Person List</h2> <table class="glyphicon glyphicon-calendar"> <tr> <th>Id</th> <th>Name</th> <th>Age</th> </tr> <tr th:each="person : ${people}"> <td th:text="${person.id}"></td> <td th:text="${person.name}"></td> <td th:text="${person.Age}"></td> </tr> </table> </div> </body> </html>
MVC模式测试
现在,我们终于可以运行我们的应用程序,以查看其运行情况。
但是应用程序不是这里的重点。
重点是使这三个组件完全分开,这非常好观察。
但是,下面的图像显示了项目输出。
MVC设计模式的优势
使用MVC模式有很多优点。
让我们在这里说明其中一些:
MVC允许快速的应用程序开发。
如果我们简单地预先定义模型层并将此信息传递给UI开发团队,那么当后端开发人员设计应用程序Controllers及其背后的逻辑时,他们便可以并行创建Views,从而加快了开发速度。在更改视图机制时,控制器层甚至不必知道数据的去向。
它只知道逻辑视图名称,甚至不知道HTML扩展名。
因此,在不影响Controller的情况下切换到基于Angular的视图非常容易。MVC模式强调应用程序不同组件之间的低耦合。
因此,View层不依赖于服务层,只有Controller依赖于它,即使依赖于接口,也不依赖于具体的实现。