一、MVC模式介绍
- 模型Model:业务逻辑层,业务流程/状态的处理以及数据模型的制定。
- 视图View:表示层,与用户实现交互的界面,视图上数据的采集和处理以及用户请求的处理。不能有任何业务逻辑。
- 控制层Controller:控制层,控制业务流程,让Model和View协调工作。可以看作是一个分发器,不做数据判断、处理,完成所有的请求、流程控制。
MVC的优势:数据和显示分离,有利于松耦合方法的实现(详见松耦合的理解和第一问)。
松耦合的理解:软件设计中的“耦合”指,两个功能函数之间的依赖程度。“松耦合”的方法是指功能函数之间,尽量依赖程度不要太高,否则修改完一个底层函数后,会对多个上层函数,进行大量的测试。一般来说,底层函数功能尽量单一,尽量避免修改底层函数。功能相近的函数,可以设计2个以上,不要为了减少代码量,把一个函数的功能设计的太多。
(一)问:MVC设计模式与传统Web开发模式的区别?
答:传统web开发模式是分为视图、业务逻辑两层,是水平划分的层次,对于开发者来说需要并行考虑整个程序的代码,容易混淆,不能很好地分工开发与管理;而MVC则是垂直方向上划分的三层,能做到数据的处理和显示的分离,从而最大化地重复利用代码,而且多个视图能共享一个模型,由于模型是自包含的、与视图和控制层分离的,对开发者来说很容易改变应用程序的数据层和业务逻辑,避免了相互干扰的混乱局面。另外,这样的分离结构清晰,也有利于开发、维护的分工协作,大家各司其职,更好地管理程序代码。
(二)问:接口定义及其实现分开的好处?
答:在回答该问题前,首先要明白:什么是接口?
接口是一系列方法的声明,是一些方法特征的集合(就是给外部程序调用的)。接口在不同的地方被不同的类实现,就像一个角色,拥有特定的属性,但是可以有很多演员来表演这个角色,所以,不同的class可以实现不同的功能。综上所述,当我们添加新的class进行程序扩展时,原有的操作接口的代码不需要进行修改,直接在新的class中进行功能实现,这样就使得程序易于扩展。如果功能模块要更新也比较简单,只更新此模块就好,不用整个软件重新更新。这样,可以减少应用程序编程、测试、维护的时间,从而缩短开发周期。
二、MVC模式初体验
建立对应的包:
- Controller(控制层):调用业务层的接口来控制业务流程。
@RestController
@RequestMapping("/api/v1/hello")
public class HelloController {
@Autowired
private HelloService helloService;
@GetMapping("list")
public JsonData list(){
List<Hello> list=helloService.listHello();
return JsonData.buildSuccess(list);
}
}
- Domain(数据映射):数据类,数据定义。
package com.example.demo1.domain;
import java.util.Date;
public class Hello {
private int id;
private String title;
private String summary;
private Date creatTime;
public Hello(int id, String title, String summary) {
this.id = id;
this.title = title;
this.summary = summary;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getSummary() {
return summary;
}
public void setSummary(String summary) {
this.summary = summary;
}
public Date getCreatTime() {
return creatTime;
}
public void setCreatTime(Date creatTime) {
this.creatTime = creatTime;
}
public Hello(int id, String title, String summary, Date creatTime) {
this.id = id;
this.title = title;
this.summary = summary;
this.creatTime = creatTime;
}
@Override
public String toString() {
return "Hello{" +
"id=" + id +
", title='" + title + '\'' +
", summary='" + summary + '\'' +
", creatTime=" + creatTime +
'}';
}
}
- Mapper(数据访问层):数据访问类,存放数据,定义用户名、密码等。负责与数据库进行联络的一些任务都封装在此。数据源配置以及有关数据库连接的参数配置都在Spring的配置文件中进行配置。
package com.example.demo1.mapper;
import com.example.demo1.domain.Hello;
import org.springframework.stereotype.Repository;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Repository
public class HelloMapper {
private static Map<Integer, Hello> helloMap=new HashMap<>();
static {
helloMap.put(1,new Hello(1,"hello","hello,hello"));
helloMap.put(2,new Hello(2,"World",""));
}
public List<Hello> listHello(){
List<Hello> list=new ArrayList<>();
list.addAll(helloMap.values());
return list;
}
}
- Service(业务层):主要负责业务模块的逻辑应用设计。在初体验工程中,首先定义接口,再实现接口。在这层,会调用mapper中定义或连接的数据。业务层的封装可保证通用业务逻辑的独立性,提高重复利用率。
接口:
package com.example.demo1.service;
import com.example.demo1.domain.Hello;
import java.util.List;
public interface HelloService {
List<Hello> listHello();
}
接口实现:
package com.example.demo1.service.impl;
import com.example.demo1.domain.Hello;
import com.example.demo1.mapper.HelloMapper;
import com.example.demo1.service.HelloService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class HelloServiceImpl implements HelloService {
@Autowired
private HelloMapper helloMapper;
@Override
public List<Hello> listHello(){
return helloMapper.listHello();
}
}
- Utils(工具类):返回JSONDate的信息(code,data,message)
package com.example.demo1;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.RestController;
@SpringBootApplication
@RestController
public class Demo1Application {
public static void main(String[] args) {
SpringApplication.run(Demo1Application.class, args);
}
}
欢迎留言!